fix(bedrock): strip "caller: null" from tool_use blocks to prevent Bedrock HTTP 400#1566
Open
xodn348 wants to merge 1 commit into
Open
fix(bedrock): strip "caller: null" from tool_use blocks to prevent Bedrock HTTP 400#1566xodn348 wants to merge 1 commit into
xodn348 wants to merge 1 commit into
Conversation
…o Bedrock Bedrock rejects HTTP 400 when a tool_use or server_tool_use content block contains "caller": null. This happens when callers convert a response ToolUseBlock (where caller is Optional[Caller] = None) to a dict via .to_dict() without exclude_none=True and then pass that dict back as part of a follow-up messages request. Add _strip_null_caller_from_tool_use() in the Bedrock client's _prepare_options() to remove the key before the payload is sent. Bedrock is stricter than the standard API about this field; the fix is intentionally scoped to the Bedrock code path. Fixes anthropics#1454
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.
Summary
When a Bedrock streaming or non-streaming response includes a
tool_useblock where thecallerfield isNone(the common case for model-invoked tools with no explicit caller), calling.to_dict()on the resultingToolUseBlockobject produces{"caller": null, ...}. When this dict is then passed back as part of a follow-upmessages.createrequest, Bedrock returns HTTP 400 with"messages.<n>.content.<m>.tool_use.caller: Input should be a valid dictionary or object to extract fields from"and the conversation loop breaks.The root cause is a type asymmetry between the response model (
ToolUseBlock.caller: Optional[Caller] = None) and the request param type (ToolUseBlockParam.caller: Callerwithtotal=False): the response type allowsNone, but the request type requires the key to be absent (notnull) when there is no caller. The standard Anthropic and Vertex APIs are lenient aboutcaller: null, but Bedrock validates the field strictly.The fix adds
_strip_null_caller_from_tool_use()— called inside_prepare_options()in the Bedrock client — to remove thecallerkey from anytool_use/server_tool_usecontent block where it isNonebefore the payload is serialised and sent. The logic is intentionally scoped to the Bedrock code path because only Bedrock enforces this constraint.Issue
Fixes #1454
Local verification
Risk
The change only affects the Bedrock code path (
_prepare_optionsinsrc/anthropic/lib/bedrock/_client.py). It removescaller: nullfromtool_useandserver_tool_usecontent blocks — a value that Bedrock already rejects with a 400, so no previously-working request can break. Users who explicitly setcallerto a non-NoneCallerobject are unaffected; onlyNonevalues are dropped.