This is a minimal reproduction of an issue where stream.append() returns [Object object] when passing an object directly, despite the TypeScript types suggesting this is valid.
In apps/trigger/src/emit-messages.ts, the following code produces [Object object] in the stream:
const payload = { message: "one" }; await messageStream.append(payload); // Results in "[Object object]"
Expected: The stream should contain {"message":"one"}
Actual: The stream contains "[Object object]"
stream.append() expects a BodyInit (string, Blob, etc.) at runtime, but the TypeScript types incorrectly suggest it accepts plain objects. When you pass an object, JavaScript calls .toString() on it, resulting in "[Object object]".
In the streaming job, stringify the json directly:
await messageStream.append( JSON.stringify(payload) as unknown as { message: string } );
Then parse it in the messageStream.read() call.
-
Clone and install dependencies:
pnpm install
-
Start the server Find the TRIGGER_SECRET_KEY for your project, then:
TRIGGER_SECRET_KEY=... pnpm dev
-
Open http://localhost:3000 and click "Start Stream"
You should see the stream error, because the messages are not correctly being serialized or deserialized.
- Make the following changes:
// Bug demonstration: typescript thinks chunk is an object, but it's actually // a string. Specifically not commenting in the next line, to demonstrate the bug. // const data = JSON.parse(chunk as unknown as string); // console.log("Parsed chunk:", data, "Type:", typeof data); // res.write(JSON.stringify(data) + "\n"); res.write(JSON.stringify(chunk) + "\n");
To:
// Bug demonstration: typescript thinks chunk is an object, but it's actually // a string. Specifically not commenting in the next line, to demonstrate the bug. const data = JSON.parse(chunk as unknown as string); console.log("Parsed chunk:", data, "Type:", typeof data); res.write(JSON.stringify(data) + "\n"); // res.write(JSON.stringify(chunk) + "\n");
and:
// BUG DEMONSTRATION: // The TypeScript types suggest we can pass an object directly to append(), // but at runtime this results in "[Object object]" because append() expects // a BodyInit (string, Blob, etc.) and JavaScript calls .toString() on objects. // // To fix this, you need to use JSON.stringify(): // await messageStream.append(JSON.stringify(payload) as unknown as { message: string }); // // But we're NOT doing that here to demonstrate the bug: // await messageStream.append(payload); await messageStream.append( JSON.stringify(payload) as unknown as { message: string } );
to:
// BUG DEMONSTRATION: // The TypeScript types suggest we can pass an object directly to append(), // but at runtime this results in "[Object object]" because append() expects // a BodyInit (string, Blob, etc.) and JavaScript calls .toString() on objects. // // To fix this, you need to use JSON.stringify(): // await messageStream.append(JSON.stringify(payload) as unknown as { message: string }); // // But we're NOT doing that here to demonstrate the bug: await messageStream.append(payload); // await messageStream.append( // JSON.stringify(payload) as unknown as { message: string } // );
- Reload the localhost:3000 page and observe the stream works as expected and displays the messages.
├── apps/
│ ├── frontend/ # React + Vite (port 3000)
│ ├── backend/ # Express server (port 4000)
│ └── trigger/ # Trigger.dev tasks
├── package.json
├── pnpm-workspace.yaml
└── turbo.json
@trigger.dev/sdk: ^4.3.1@trigger.dev/build: ^4.3.1trigger.dev: ^4.3.1