Description
When sending conversation history to Anthropic models (e.g. Claude Opus), the API rejects requests with:
tool_use ids found without tool_result blocks immediately after
This happens when compaction or history truncation leaves orphaned tool_use content blocks in assistant messages without corresponding tool_result blocks in the following user message.
Root Cause
validateAnthropicTurns() (in pi-embedded-helpers-*.js) currently merges consecutive user turns but does not strip dangling tool_use blocks from assistant messages when corresponding tool_result blocks are missing from the next user turn.
The existing repairToolUseResultPairing operates at the message level (pairing assistant + toolResult messages), but doesn't handle mismatches at the content-block level within messages.
Steps to Reproduce
- Have a conversation with multiple tool calls in a session
- After compaction trims history, some
tool_use blocks may lose their paired tool_result blocks
- Send the compacted history to an Anthropic model
- Anthropic rejects with the error above
Expected Behavior
validateAnthropicTurns() should strip tool_use content blocks from assistant messages when the immediately following user message does not contain a matching tool_result block (by tool_use_id). Non-tool content in the assistant message should be preserved; if all content would be removed, a minimal fallback text block should be inserted.
Workaround
We applied a local hotfix to the dist files adding a stripDanglingAnthropicToolUses() step inside validateAnthropicTurns(). This resolves the issue but is overwritten on update.
Environment
- OpenClaw 2026.3.2
- Model: anthropic/claude-opus-4-6
- Channel: Telegram (embedded agent path)
Description
When sending conversation history to Anthropic models (e.g. Claude Opus), the API rejects requests with:
This happens when compaction or history truncation leaves orphaned
tool_usecontent blocks in assistant messages without correspondingtool_resultblocks in the following user message.Root Cause
validateAnthropicTurns()(inpi-embedded-helpers-*.js) currently merges consecutive user turns but does not strip danglingtool_useblocks from assistant messages when correspondingtool_resultblocks are missing from the next user turn.The existing
repairToolUseResultPairingoperates at the message level (pairing assistant + toolResult messages), but doesn't handle mismatches at the content-block level within messages.Steps to Reproduce
tool_useblocks may lose their pairedtool_resultblocksExpected Behavior
validateAnthropicTurns()should striptool_usecontent blocks from assistant messages when the immediately following user message does not contain a matchingtool_resultblock (bytool_use_id). Non-tool content in the assistant message should be preserved; if all content would be removed, a minimal fallback text block should be inserted.Workaround
We applied a local hotfix to the dist files adding a
stripDanglingAnthropicToolUses()step insidevalidateAnthropicTurns(). This resolves the issue but is overwritten on update.Environment