[integration][anthropic] Don't assume the first content block is text#916
Merged
Merged
Conversation
When the Anthropic model calls a tool, the response commonly contains only a tool_use block, so message.content[0] is a ToolUseBlock. Reading message.content[0].text then raised AttributeError: 'ToolUseBlock' object has no attribute 'text'. The same block already iterates message.content filtering by type == "tool_use", so the mixed block types are known here. Pick the first text block instead (falling back to "" when there is none), and reuse it in both the tool_use and plain-text return paths. Add unit tests (mocked client, no API key) covering a tool_use response with no leading text, one with a leading text block, and a plain text response. Closes apache#914
wenjin272
marked this pull request as ready for review
July 20, 2026 03:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue: #914
Purpose of change
AnthropicChatModelConnection.chatread the response text viamessage.content[0].text. When the model calls a tool, the response commonlycontains only a
tool_useblock, socontent[0]is aToolUseBlockand.textraisedAttributeError: 'ToolUseBlock' object has no attribute 'text'.Both the
tool_useand the plain-text return paths used this unsafe access,even though the code just above already iterates
message.contentfiltering bytype == "tool_use"— so the blocks are known to be mixed-type there.Pick the first text block instead (falling back to
""when there is none) andreuse it in both return paths.
Closes #914
Tests
Added
test_anthropic_response_parsing.pywith unit tests that mock the client,so they need no API key and run in the regular unit test job: a tool_use
response with no leading text, one with a leading text block, and a plain text
response.
test_tool_use_response_without_leading_textfails onmainwithAttributeError: 'ToolUseBlock' object has no attribute 'text'and passes withthis change.
pytest flink_agents/integrations/chat_models/anthropic/tests/: 5 passed,2 skipped (the existing API-key integration tests).
ruff check --no-fix/ruff format --check(pinned 0.11.13): clean.API
No.
chat()keeps its signature and still returns aChatMessage. Textresponses are unaffected — the first text block is the same value
content[0]used to yield — it only stops crashing when the first block is not text.
Documentation
doc-neededdoc-not-neededdoc-included