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