Bug Description
When using Agent Maestro as a proxy for Claude Code (or OpenClaw), the Anthropic API returns a 400 error about mismatched tool_use_id in tool_result blocks after extended tool-using conversations. This makes Agent Maestro unusable for any non-trivial agent workflow.
Error message:
messages.0.content.0: unexpected `tool_use_id` found in `tool_result` blocks: <id>.
Each tool_result block must have a corresponding tool_use block in the previous message.
Root Cause Analysis
The Problem
The Anthropic Messages API enforces a strict invariant: every tool_result content block in a user message must reference a tool_use_id from a tool_use block in the immediately preceding assistant message. This is a hard constraint — violating it produces a 400 error.
When Agent Maestro converts Anthropic messages → VS Code Language Model API format → sends to the model, the VS Code LM API (Copilot backend) internally processes and may truncate/compact the conversation history. However, Agent Maestro does NOT actually re-validate the original Anthropic message array before forwarding it. The error actually comes from the VS Code LM API's internal handling — it passes the messages to its own backend which apparently enforces similar constraints.
Why the Current Workaround Is Insufficient
In anthropicRoutes.ts (lines 481-486), there's an existing workaround:
const isContextWindowExceeded =
errorMessage.includes("unexpected `tool_use_id` found in `tool_result` blocks") &&
maxInputTokens > 0 &&
inputTokens > maxInputTokens;
This workaround only triggers when inputTokens > maxInputTokens, meaning it only handles the case where the context window is exceeded. However, the pairing error frequently occurs within the context window limit — the VS Code LM API backend can reject tool_use/tool_result pairings for various reasons unrelated to context length.
When the workaround DOES trigger, it returns a fake model_context_window_exceeded stop reason with inflated token counts to force the client (Claude Code/OpenClaw) to auto-compact. This is a reasonable strategy, but since it rarely triggers, most errors just bubble up as 500 internal server errors.
Message Flow
OpenClaw/Claude Code → Agent Maestro (localhost:23333/api/anthropic/v1/messages)
→ convertAnthropicMessagesToVSCode() [src/server/utils/anthropic.ts]
→ client.sendRequest() [VS Code Language Model API]
→ VS Code LM API backend (Copilot)
→ Error: "unexpected tool_use_id found in tool_result blocks"
→ Caught in catch block of anthropicRoutes.ts
→ Workaround condition NOT met (inputTokens <= maxInputTokens)
→ Returns 500 error to OpenClaw/Claude Code
→ OpenClaw completely broken
Proposed Fix
Add a message sanitization step before sending to the VS Code LM API that validates and repairs tool_use/tool_result pairing:
- Before calling
client.sendRequest(), scan the Anthropic messages array
- For each user message containing
tool_result blocks, verify that the immediately preceding assistant message contains matching tool_use blocks with the same IDs
- For orphaned
tool_result blocks (no matching tool_use in the previous assistant message):
- Either inject a synthetic
tool_use block into the preceding assistant message
- Or remove the orphaned
tool_result block and convert its content to a plain text block
- For orphaned
tool_use blocks in assistant messages (no matching tool_result in the next user message):
- Either inject a synthetic
tool_result block
- Or remove the orphaned
tool_use block
Additionally, the catch block workaround should be broadened: when the "unexpected tool_use_id" error occurs, it should ALWAYS return the model_context_window_exceeded fake response (not just when inputTokens > maxInputTokens), so the client always gets a chance to compact and retry.
Reproduction Steps
- Install Agent Maestro v2.8.1 in VS Code
- Configure OpenClaw or Claude Code to use
http://localhost:23333/api/anthropic as the API base URL
- Start a conversation that uses tools (e.g., file reading, bash commands)
- After several rounds of tool use (typically 5-10+ tool calls), the error appears
- Once the error occurs, the session becomes completely unusable — every subsequent request also fails
Environment
- Agent Maestro: v2.8.1
- VS Code: 1.100+
- Client: OpenClaw 2026.2.24 / Claude Code
- Model: claude-opus-4-20250514 (via VS Code Copilot)
Impact
This bug makes Agent Maestro completely unusable for any agent workflow that involves tool use (which is the primary use case for Claude Code / OpenClaw). After a few tool calls, the session breaks and cannot recover without restarting the entire conversation.
Bug Description
When using Agent Maestro as a proxy for Claude Code (or OpenClaw), the Anthropic API returns a 400 error about mismatched
tool_use_idintool_resultblocks after extended tool-using conversations. This makes Agent Maestro unusable for any non-trivial agent workflow.Error message:
Root Cause Analysis
The Problem
The Anthropic Messages API enforces a strict invariant: every
tool_resultcontent block in a user message must reference atool_use_idfrom atool_useblock in the immediately preceding assistant message. This is a hard constraint — violating it produces a 400 error.When Agent Maestro converts Anthropic messages → VS Code Language Model API format → sends to the model, the VS Code LM API (Copilot backend) internally processes and may truncate/compact the conversation history. However, Agent Maestro does NOT actually re-validate the original Anthropic message array before forwarding it. The error actually comes from the VS Code LM API's internal handling — it passes the messages to its own backend which apparently enforces similar constraints.
Why the Current Workaround Is Insufficient
In
anthropicRoutes.ts(lines 481-486), there's an existing workaround:This workaround only triggers when
inputTokens > maxInputTokens, meaning it only handles the case where the context window is exceeded. However, the pairing error frequently occurs within the context window limit — the VS Code LM API backend can reject tool_use/tool_result pairings for various reasons unrelated to context length.When the workaround DOES trigger, it returns a fake
model_context_window_exceededstop reason with inflated token counts to force the client (Claude Code/OpenClaw) to auto-compact. This is a reasonable strategy, but since it rarely triggers, most errors just bubble up as 500 internal server errors.Message Flow
Proposed Fix
Add a message sanitization step before sending to the VS Code LM API that validates and repairs
tool_use/tool_resultpairing:client.sendRequest(), scan the Anthropic messages arraytool_resultblocks, verify that the immediately preceding assistant message contains matchingtool_useblocks with the same IDstool_resultblocks (no matchingtool_usein the previous assistant message):tool_useblock into the preceding assistant messagetool_resultblock and convert its content to a plain text blocktool_useblocks in assistant messages (no matchingtool_resultin the next user message):tool_resultblocktool_useblockAdditionally, the catch block workaround should be broadened: when the
"unexpected tool_use_id"error occurs, it should ALWAYS return themodel_context_window_exceededfake response (not just wheninputTokens > maxInputTokens), so the client always gets a chance to compact and retry.Reproduction Steps
http://localhost:23333/api/anthropicas the API base URLEnvironment
Impact
This bug makes Agent Maestro completely unusable for any agent workflow that involves tool use (which is the primary use case for Claude Code / OpenClaw). After a few tool calls, the session breaks and cannot recover without restarting the entire conversation.