You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
v2: Anthropic Messages transform throws on round-trip of provider-executed tool results it doesn't recognize, instead of degrading #53633
packages/llm/src/protocols/anthropic-messages.ts refuses to lower any assistant history containing a provider-executed (providerExecuted: true) tool-result whose tool name is not one of Anthropic's three native server tools (web_search, code_execution, web_fetch). Instead of degrading the unrecognized result, it fails the whole request with:
"Anthropic Messages does not know how to round-trip server tool result for "
This happens before any network call, during message lowering. The practical effect: once a conversation's history contains a provider-executed tool result that isn't one of those three (for example a provider-executed read), that conversation can no longer be continued on an Anthropic-API provider (e.g. Anthropic direct, Bedrock, Vertex). Switching provider mid-conversation — or otherwise replaying that history to an Anthropic route — is permanently blocked for that session.
Root cause
packages/llm/src/protocols/anthropic-messages.ts
The name mapper only knows three server tools (lines ~293-298):
lowerServerToolResult throws on anything else (lines ~300-305):
constlowerServerToolResult=Effect.fn("AnthropicMessages.lowerServerToolResult")(function*(part: ToolResultPart){constwireType=serverToolResultType(part.name)if(!wireType)returnyield*invalid(`Anthropic Messages does not know how to round-trip server tool result for ${part.name}`)return{type: wireType,tool_use_id: part.id,content: part.result.value}satisfiesAnthropicServerToolResultBlock})
And it is reached for every provider-executed tool-result during lowering (lines ~461-463):
So any providerExecuted: true tool-result with a name outside those three hard-fails the request.
Precedent
This is the Anthropic Messages analog of #29159 ("fix(llm): replay OpenAI Responses hosted tool history as native input items"), which was the same defect on the OpenAI Responses adapter — assistant history containing provider-executed hosted tool results was rejected during lowering with "only support text, reasoning, and tool-call content". That was fixed by teaching lowerMessages to lower the provider-executed pairs instead of rejecting them. The Anthropic Messages transform has the equivalent gap and never received the equivalent treatment.
Related: #45261 also concerns provider-executed tool calls breaking the rest of an Anthropic session (via repairToolCall), i.e. a nearby class of "provider-executed content is mishandled on the Anthropic path".
Suggested direction (not prescriptive)
Mirror #29159: in the Anthropic Messages transform, handle an unrecognized provider-executed tool-result by degrading it rather than throwing — e.g. lowering it to a normal content block (text, or a best-effort representation of the structured result) so the history remains replayable.
One caveat worth the maintainers' judgement: a native Anthropic tool_result block normally pairs with a client tool_use, which a provider-executed call does not have, so the exact safe representation (plain text vs. a synthesized block) needs deciding. The key ask is simply that an unrecognized provider-executed result should not hard-fail the entire request — a conversation should remain portable to an Anthropic provider.
Plugins
No response
OpenCode version
v2.0.18.
Steps to reproduce
Have a conversation whose assistant history contains a tool-result with providerExecuted: true and a tool name that is not web_search / code_execution / web_fetch (any provider/runtime that surfaces a locally/externally executed tool as provider-executed will produce one — e.g. a provider-executed read).
Continue that conversation on an Anthropic-API route (Anthropic, Bedrock, or Vertex Anthropic).
The request fails during lowering with Anthropic Messages does not know how to round-trip server tool result for — no network call is made.
Thanks for the detailed report. I can confirm this on v2.0.18, and the current v2 branch behaves the same way.
I tested it at the protocol level: I built a request for the Anthropic Messages route whose assistant history holds a providerExecuted: true tool-call/tool-result pair, then compiled it.
With web_search the request compiles normally.
With other names (read, file_search, tool_search_tool_regex) it fails during lowering, before any network call, with Anthropic Messages does not know how to round-trip server tool result for <name>.
I couldn't test a real provider switch end to end here, so if you can share which provider/model produced the provider-executed result in your session, that would help pin down the realistic trigger.
The realistic trigger is a mid-session provider switch — starting on claude-code/claude-opus-5 (which routes through the Claude Code CLI) and switching to google-vertex/claude-opus-4-6@default (Vertex AI, Anthropic Messages protocol) within the same conversation.
The Claude Code CLI executes tools natively (e.g. read, bash, edit), and those results end up in the conversation history as providerExecuted: true. When the conversation then continues on the Vertex provider, the Anthropic Messages transform fails on those tool results during lowering.
The switch can happen for any reason — manual model change, or automated (e.g. rate-limit-triggered). The effect is that any conversation that has used Claude Code's native tools becomes permanently non-portable to an Anthropic-API provider.
Still reproducible on dev — anthropic-messages.ts:608 throws does not know how to round-trip server tool result for any provider-executed tool outside web_search / code_execution / web_fetch.
Activity
opencode-agent commentedon Oct 7, 2026
Thanks for the detailed report. I can confirm this on v2.0.18, and the current
v2branch behaves the same way.I tested it at the protocol level: I built a request for the Anthropic Messages route whose assistant history holds a
providerExecuted: truetool-call/tool-result pair, then compiled it.web_searchthe request compiles normally.read,file_search,tool_search_tool_regex) it fails during lowering, before any network call, withAnthropic Messages does not know how to round-trip server tool result for <name>.I couldn't test a real provider switch end to end here, so if you can share which provider/model produced the provider-executed result in your session, that would help pin down the realistic trigger.
nic-lan commentedon Oct 8, 2026
The realistic trigger is a mid-session provider switch — starting on
claude-code/claude-opus-5(which routes through the Claude Code CLI) and switching togoogle-vertex/claude-opus-4-6@default(Vertex AI, Anthropic Messages protocol) within the same conversation.The Claude Code CLI executes tools natively (e.g.
read,bash,edit), and those results end up in the conversation history asproviderExecuted: true. When the conversation then continues on the Vertex provider, the Anthropic Messages transform fails on those tool results during lowering.The switch can happen for any reason — manual model change, or automated (e.g. rate-limit-triggered). The effect is that any conversation that has used Claude Code's native tools becomes permanently non-portable to an Anthropic-API provider.
nic-lan commentedon Oct 19, 2026
Still reproducible on
dev—anthropic-messages.ts:608throwsdoes not know how to round-trip server tool resultfor any provider-executed tool outsideweb_search/code_execution/web_fetch.PR with a fix and regression tests: #55560