You stream a response that includes a tool call and your JSON.parse throws on every delta. What should the code do instead?
Why D is the answer
Join the partial_json strings and parse at content_block_stop
Tool input arrives as input_json_delta events holding partial JSON strings. They are not valid JSON one at a time, so collect them and parse when the block stops.
In detail
- Tool input arrives as input_json_delta events holding partial strings.
- One fragment is not valid JSON, so parsing each one fails.
- Collect the strings, then parse at content_block_stop.
- Keep a separate buffer for each content block index.
Use case
An illustrative scenario, not a real incident.
A streaming agent crashes on its first tool call, because the code parses each fragment. Buffering partial_json and parsing at content_block_stop fixes it.
See it in different ways
flowchart LR A["message_start"] --> B["content_block_start"] B --> C["content_block_delta"] C --> C C --> D["content_block_stop"] D -->|"Next block"| B D --> E["message_delta"] E --> F["message_stop"]
sequenceDiagram participant A as API participant C as Your client A-->>C: message_start A-->>C: content_block_start A-->>C: content_block_delta, many times A-->>C: content_block_stop A-->>C: message_delta A-->>C: message_stop
flowchart LR S0["input_json_delta"] --> S1["Append to a buffer"] --> S2["content_block_stop"] --> S3["Parse the full string"]
Key point: Partial JSON is valid only once it is complete.
Why the other options are wrong
- A. Retry the request until a delta parses cleanly
- Partial fragments will never parse, however many times you retry.
- B. Switch tool_choice to none while streaming
- tool_choice none stops the tool call you actually want.
- C. Disable streaming whenever tools are defined
- Streaming works with tools, so turning it off avoids the bug rather than fixing it.

