fix(mimic): rewrite tool_use names in messages to match renamed tools#2340
Open
iFwu wants to merge 1 commit intoWei-Shaw:mainfrom
Open
fix(mimic): rewrite tool_use names in messages to match renamed tools#2340iFwu wants to merge 1 commit intoWei-Shaw:mainfrom
iFwu wants to merge 1 commit intoWei-Shaw:mainfrom
Conversation
The Claude Code mimic path rewrites tool names in tools[] (and
tool_choice) but left tool_use blocks in messages[] with their
original names. Anthropic validates that every tool referenced by
a tool_use block is declared in tools[], so the mismatch produces:
messages.N.content.M: Input tag 'original_name' not found in tools
(surfaced as HTTP 400 directly, or wrapped as 424 by upstream proxies
such as Bedrock gateways.)
The previous code comment asserted 'this matches Parrot; response-side
bytes.Replace will restore the names'. Parrot's behavior is fine for
Claude Code's own tool set, but breaks once the upstream client sends
additional tools (e.g. web_search) that are not part of Claude Code
and therefore get renamed here.
Fix: apply the same ToolNameRewrite to messages[].content[] blocks
where type == 'tool_use', keeping tools[], tool_choice and messages
self-consistent before the request reaches Anthropic. tool_result
blocks reference tools via tool_use_id, not name, so no change is
needed there.
A new unit test covers the full rewrite flow and guards against
server tools (type != '') being affected.
Contributor
|
All contributors have signed the CLA. ✅ |
Author
|
I have read the CLA Document and I hereby sign the CLA |
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
claude_code_mimicrewrites tool names intools[]andtool_choice, it currently leavesmessages[].content[].nameblocks (type == "tool_use") with their original names. Anthropic validates that every tool referenced by atool_useblock is declared intools[], so the mismatch produces an error like:surfaced as HTTP 400 directly, or wrapped as 424 by upstream proxies (e.g. Bedrock gateways).
Reproduction
extra.claude_code_mimic = trueweb_search, or any user-defined tool whose name gets rewritten)tool_useblocks referencing the original nameThe rewrite renames
tools[*].name, but the oldertool_useblocks inmessagesstill point at the old name → Anthropic rejects the request.Why Parrot didn't need this
The existing code comment referenced Parrot's behavior:
Parrot only mimics Claude Code's built-in tool set, so by construction
messages[].nameandtools[].nameuse the same set of names, and there is no cross-turn mismatch. sub2api is more permissive — clients may send anytools[]— so the assumption no longer holds for historicaltool_useblocks, which were named back when the rewrite hadn't been applied yet.Fix
Apply the same
ToolNameRewrite.Forwardmap tomessages[].content[]entries wheretype == "tool_use", keepingtools[],tool_choiceandmessagesself-consistent before the request hits Anthropic.tool_resultblocks reference tools viatool_use_id, notname, so they don't need changes.web_search_20250305with non-emptytype) are still skipped byshouldMimicToolName, so they aren't touched.bytes.Replacestill restores the original names in the final output, so the client sees no difference.Testing
Added
TestApplyToolNameRewriteToBody_RenamesToolUseInMessagestogateway_tool_rewrite_test.go, covering:tools[*].namerewrittentool_choice.namerewrittenmessages[*].content[*].name(type == "tool_use") rewrittentype != "") untouchedtool_resultblocks untouched (nonamefield)Validated in production: previously the affected account hit 424 on every multi-turn request containing
web_searchtool_use history; after this fix those requests succeed.