Prerequisites
Description
On the Anthropic-compatible endpoint (/anthropic/v1/messages), a client tool named web_search or web_fetch (a regular tool_use block for a function tool the caller defined) is converted to a web_search_call / web_fetch_call instead of a function_call.
anthropicToolUseBlockToResponsesMessage (core/providers/anthropic/responses.go) decides by name alone. It is used by the grouped converter for both tool_use and server_tool_use blocks, so it cannot tell our function tool apart from Anthropic's server tool. The ungrouped converter already switches on block type and does not have this problem.
The matching tool_result stays a function_call_output. On Bedrock the web_search_call is rewritten as a nova_grounding server tool with its own synthetic result, so the real tool_result has no toolUse left in the previous assistant turn and Bedrock rejects the request.
Because the bad item is in the replayed history, every later turn in that conversation fails too, including turns that don't search.
Steps to reproduce
- Route a Claude model to Bedrock (e.g.
bedrock/global.anthropic.claude-sonnet-4-6).
- Send
/anthropic/v1/messages with a function tool named web_search (e.g. {"name":"web_search","input_schema":{"type":"object","properties":{"query":{"type":"string"}}}}).
- Replay a turn where the assistant called it and the user returned the result:
- assistant:
{"type":"tool_use","id":"toolu_1","name":"web_search","input":{"query":"x"}}
- user:
{"type":"tool_result","tool_use_id":"toolu_1","content":"..."}
- Observe the 400 below. The same payload sent directly to Bedrock (Converse or InvokeModel) succeeds; tools with any other name take the normal
function_call path.
Expected behavior
A tool_use block for a client tool named web_search / web_fetch is converted to a function_call with its name and arguments, like any other function tool.
Actual behavior
It becomes a web_search_call / web_fetch_call, the tool_result is orphaned, and Bedrock returns 400 ValidationException.
Affected area(s)
Core (Go)
Version
transports/v2.1.0 and transports/v2.2.2. Still present on dev (955ffa3).
Relevant logs/output
{"type":"ValidationException","is_bifrost_error":false,"status_code":400,"error":{"type":"ValidationException","message":"The number of toolResult blocks at messages.10.content exceeds the number of toolUse blocks of previous turn."},"extra_fields":{"provider":"bedrock","request_type":"responses_stream"}}
Severity
High (major functionality broken)
Fix with regression tests: #8079. It only maps these names when the block type is server_tool_use.
Prerequisites
Description
On the Anthropic-compatible endpoint (
/anthropic/v1/messages), a client tool namedweb_searchorweb_fetch(a regulartool_useblock for a function tool the caller defined) is converted to aweb_search_call/web_fetch_callinstead of afunction_call.anthropicToolUseBlockToResponsesMessage(core/providers/anthropic/responses.go) decides by name alone. It is used by the grouped converter for bothtool_useandserver_tool_useblocks, so it cannot tell our function tool apart from Anthropic's server tool. The ungrouped converter already switches on block type and does not have this problem.The matching
tool_resultstays afunction_call_output. On Bedrock theweb_search_callis rewritten as anova_groundingserver tool with its own synthetic result, so the realtool_resulthas notoolUseleft in the previous assistant turn and Bedrock rejects the request.Because the bad item is in the replayed history, every later turn in that conversation fails too, including turns that don't search.
Steps to reproduce
bedrock/global.anthropic.claude-sonnet-4-6)./anthropic/v1/messageswith a function tool namedweb_search(e.g.{"name":"web_search","input_schema":{"type":"object","properties":{"query":{"type":"string"}}}}).{"type":"tool_use","id":"toolu_1","name":"web_search","input":{"query":"x"}}{"type":"tool_result","tool_use_id":"toolu_1","content":"..."}function_callpath.Expected behavior
A
tool_useblock for a client tool namedweb_search/web_fetchis converted to afunction_callwith its name and arguments, like any other function tool.Actual behavior
It becomes a
web_search_call/web_fetch_call, thetool_resultis orphaned, and Bedrock returns 400 ValidationException.Affected area(s)
Core (Go)
Version
transports/v2.1.0 and transports/v2.2.2. Still present on
dev(955ffa3).Relevant logs/output
{"type":"ValidationException","is_bifrost_error":false,"status_code":400,"error":{"type":"ValidationException","message":"The number of toolResult blocks at messages.10.content exceeds the number of toolUse blocks of previous turn."},"extra_fields":{"provider":"bedrock","request_type":"responses_stream"}}Severity
High (major functionality broken)
Fix with regression tests: #8079. It only maps these names when the block type is
server_tool_use.