104000: Streamed message could not be finalized
streamed_message_finalize_failedCompleting or cancelling a streamed message failed. One of its appends was not published, and the follow-up attempt to repair it by re-sending the accumulated content in a single update also failed.
What you should do
The step producing the message failed, and the partial it had streamed is left on the channel. How you recover depends on how you run the agent:
- Under a durable-execution framework such as Temporal or the Vercel Workflow DevKit, the engine retries the failed step. Keep its
stepIdstable across attempts: the SDK then supersedes the failed attempt rather than appending to it, so the retry replaces the partial on the channel and there is nothing error-specific for you to add. - Without a durable-execution framework, the step will not re-run on its own. Produce the reply again by starting a fresh run, which your application requests rather than the SDK; in a chat client that request is a regenerate.
If re-runs keep failing, inspect the error's cause for the underlying publish failure rather than assuming a retry will fix it.
Why it happens
A streamed message is delivered as an initial publish followed by a series of appends, then finalized with a terminal status of complete or cancelled. Appends are sent fire-and-forget, so a failed append publish is not raised as it happens; it is noticed only when the message is finalized. At that point the SDK tries to repair the message by re-sending its full accumulated content in a single update. This error is raised when that repair publish also fails, so the message is left without a clean terminal state. The originating append failure is preserved as the error's cause.
What you'll see
The error is reported with code 104000 and status 500. The message names the affected streams, in the form unable to flush pending appends; recovery failed for stream(s): .... In the run pipe it surfaces as the cause of a run response stream error (code 104008) rather than at the top level, reaching you through the run's error handling (RunInfo.error).