Structured output stops breaking when Claude retries
3 hours ago
Version 4.4.0 of the Claude Code provider for the Vercel AI SDK fixes a failure you may have hit with streamText and a structured output: when Claude retried its answer, the stream broke. It also fixes truncated and oversized tool call inputs, and it changes one default.
Ask about this presentation
Chapters
0:00Structured output stops breaking when Claude retries
0:19A retried answer arrived as two objects
0:44partialOutputStream now delivers one object
1:08Opt back in with streamStructuredOutput
1:31Only the root answer reaches your object
1:53Tool calls finalize from the complete input
2:14Oversized tool inputs raise an error
2:32Upgrade to 4.4.0
Show transcriptHide transcript
Version 4.4.0 of the Claude Code provider for the Vercel AI SDK fixes a failure you may have hit with streamText and a structured output: when Claude retried its answer, the stream broke. It also fixes truncated and oversized tool call inputs, and it changes one default.
With streamText and an output schema, the provider forwarded the model's JSON as text the moment it arrived. Say the first attempt gives the answer as a string. The CLI rejects it for a schema mismatch, and the model retries with a number. Both attempts were already streamed, so the AI SDK parsed them as one string and threw NoObjectGeneratedError, even though the CLI's result held a valid object.
The fix changes how structured output streams. Before, partialOutputStream updated field by field. Now the provider buffers each attempt and emits the CLI-validated object once, when the run finishes, the way doGenerate already did. Tool progress, reasoning and raw events still stream live. If your UI draws a live preview of the object, this is the change you'll notice.
Want the old behavior? Pass streamStructuredOutput true in the model settings. It defaults to false because streamed text can't be taken back. A run where the model answers twice still fails, and a preview can show fields from a rejected attempt. For a safer preview, keep the default and read the raw SDK events through onSdkMessage or includeRawChunks.
Three smaller structured output fixes come with it. A subagent's own StructuredOutput call can't end up in your root object anymore. The CLI's accept and reject results for that internal tool no longer show up as unknown tool calls, in doStream or doGenerate. And recovery skips any attempt the CLI rejected.
Ordinary tool calls get a fix too. When a streamed fragment was dropped or arrived out of order, doStream could finalize the call from incomplete input, like this half-written file path. Now the complete assistant input wins, unless the streamed bytes encode the same value. And input that already streamed isn't emitted a second time.
Next, oversized tool inputs. The size check ran inside the try block meant for JSON stringify failures, so an object over the one megabyte limit came through as the string object Object. Now the error propagates. doGenerate rejects, and doStream emits an error part.
To upgrade, install the provider with npm. Version 4.x is the latest tag, for AI SDK version 7. Decide one thing first. If your app shows partial objects as they stream, accept one complete object at the end, or opt back in and live with the occasional failed run. Everyone else gets structured output that holds up when Claude retries.
ben-vargas/ai-sdk-provider-claude-code