Skip to content

useRealtimeStream returns '[object Object]' for object stream append payloads #3169

Description

@ghostyfreak

Summary

When appending object payloads to a realtime stream with stream.append(...), useRealtimeStream(...) receives chunks as "[object Object]" (or otherwise non-typed), and the Trigger dashboard also shows "[object Object]".

This breaks typed stream consumption and can cause UI progress/completion logic to miss expected events.

Versions

  • @trigger.dev/sdk: 4.4.1
  • @trigger.dev/react-hooks: 4.4.1
  • Observed in Trigger Cloud + React frontend consumer

Minimal Repro

1) Define a typed object stream

import { streams, task } from "@trigger.dev/sdk";

const eventStream = streams.define<{ type: string; step: string }>({
  id: "repro-object-stream",
});

export const reproTask = task({
  id: "repro-task",
  run: async () => {
    await eventStream.append({ type: "stage_started", step: "one" });
    await eventStream.append({ type: "stage_completed", step: "done" });
    return { ok: true };
  },
});

2) Subscribe in React

import { useRealtimeStream } from "@trigger.dev/react-hooks";

const { parts } = useRealtimeStream(eventStream, runId, { accessToken });
console.log(parts);

Observed

  • Trigger dashboard stream entries show [object Object].
  • Frontend receives string chunks like [object Object] (instead of typed objects).
  • Consumers relying on object shape (part.type) fail.

Expected

  • Object payloads appended via append(...) should round-trip as objects to useRealtimeStream.
  • Dashboard should display object payloads meaningfully (or at least preserve JSON shape).

Suspected Cause

In installed @trigger.dev/core@4.4.1, appendToStream appears to send raw body: part (without JSON serialization), which can coerce objects to [object Object] through fetch body handling.

Temporary Workaround

Serializing manually before append (e.g. JSON.stringify(...)) and normalizing on read avoids the issue, but this defeats the typed object stream ergonomics.

Extra Context

I can provide a full repo repro if useful, but the minimal snippet above should reproduce.

Activity

  1. ghostyfreak commented on Mar 4, 2026

    @ghostyfreak
    Author

    Adding the workaround we applied in production in case it helps others until this is fixed:

    What we changed

    1. Explicitly serialize stream payloads before append

      • Instead of stream.append(eventObject), we now do stream.append(JSON.stringify({ id, data: eventObject })).
      • We wrap in { id, data } to keep stable ordering metadata and a predictable decode shape.
    2. Normalize stream chunks on the client

      • useRealtimeStream(...) parts are normalized with this order:
        • If chunk already matches event schema -> use directly.
        • If chunk is string -> JSON.parse and re-check.
        • If chunk is wrapped object with data -> validate data as event.
        • Otherwise ignore chunk as malformed.
    3. Run-status fallback for completion/failure

      • We added useRealtimeRun(runId, { stopOnCompletion: true }) alongside stream subscription.
      • UI completion/failure state now resolves from either:
        • Stream terminal event, or
        • Run terminal status.

    Why this works

    • It bypasses object-body coercion to "[object Object]" by controlling serialization ourselves.
    • It hardens UI against malformed/missing stream chunks.
    • It restores reliable completion handling even when stream payloads are degraded.

    If useful, I can also share a minimal helper utility gist for serialize/normalize so others can drop it in quickly.

  2. paduc commented on Apr 2, 2026

    @paduc

    I'm experiencing the same problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions