Skip to content

fix: add missing content block types to ParsedContentBlock and ParsedBetaContentBlock#1379

Open
atishay2 wants to merge 3 commits intoanthropics:mainfrom
atishay2:fix/parsed-content-block-missing-types
Open

fix: add missing content block types to ParsedContentBlock and ParsedBetaContentBlock#1379
atishay2 wants to merge 3 commits intoanthropics:mainfrom
atishay2:fix/parsed-content-block-missing-types

Conversation

@atishay2
Copy link
Copy Markdown

Summary

ParsedContentBlock and ParsedBetaContentBlock have fallen behind their base union types as new server-generated block types were added to the API.

ParsedContentBlock (parsed_message.py) is missing:

  • ContainerUploadBlock — present in ContentBlock

ParsedBetaContentBlock (beta/parsed_beta_message.py) is missing:

  • BetaWebFetchToolResultBlock — present in BetaContentBlock
  • BetaAdvisorToolResultBlock — present in BetaContentBlock
  • BetaToolSearchToolResultBlock — present in BetaContentBlock

Impact

When the API returns any of these block types in a streaming or non-streaming response, construct_type() cannot match them against the discriminated union and silently drops them. This means get_final_message().content returns an incomplete list with no error or warning — the same class of silent data loss fixed for other server tool result types in #1364.

Fix

Add the missing imports and union members to bring ParsedContentBlock and ParsedBetaContentBlock in sync with ContentBlock and BetaContentBlock respectively.

Relates to #1364.

Atishay Tiwari added 3 commits April 11, 2026 20:56
…silently

  The __stream__ methods in Stream and AsyncStream used separate if statements
  with no else clause, causing any unrecognized event type to be silently
  dropped. This broke client.beta.sessions.events.stream() entirely since
  managed agents emit different event names (agent.message, session.status_*)
  that don't match the hardcoded Messages API event list.

  Fix: Convert if/if/if/if to if/elif/elif/elif/else in both sync and async
  __stream__ methods so unknown events pass through process_data() instead
  of being silently discarded.

  Fixes anthropics#1357
ParsedContentBlock in types/parsed_message.py only included
WebSearchToolResultBlock but was missing 5 other server tool result types:

- CodeExecutionToolResultBlock
- WebFetchToolResultBlock
- BashCodeExecutionToolResultBlock
- TextEditorCodeExecutionToolResultBlock
- ToolSearchToolResultBlock

When any of these arrived as content_block_start events during streaming,
construct_type() failed discriminated union parsing and silently dropped them
from current_snapshot.content. As a result, get_final_message().content was
missing server tool results when client tools ran concurrently with server
tools — the bug reported in anthropics#1325.

Fix: add all 5 missing types to ParsedContentBlock to match ContentBlock.

Adds sync + async regression tests with a fixture that streams both
web_search_tool_result and code_execution_tool_result blocks alongside
a concurrent client tool_use, asserting all 4 blocks are present in
get_final_message().content.

Fixes anthropics#1325
…BetaContentBlock

ParsedContentBlock was missing ContainerUploadBlock, which is present in
ContentBlock. ParsedBetaContentBlock was missing BetaWebFetchToolResultBlock,
BetaAdvisorToolResultBlock, and BetaToolSearchToolResultBlock, all of which
are present in BetaContentBlock.

When the API returns these block types in a streaming response, they are
silently dropped from get_final_message().content because construct_type()
cannot match them against the incomplete discriminated union.
@atishay2 atishay2 requested a review from a team as a code owner April 14, 2026 04:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant