{"data":{"id":"9eb75626-3939-40e4-9d98-659001d3cc55","slug":"fix-claude-code-api-error-400-tool-use-ids-were-found-without-tool-result-blocks-from-parallel-tool-execution-in-claude--zni9yy","title":"Fix Claude Code API Error 400: 'tool_use ids were found without tool_result blocks' from Parallel Tool Execution in Claude Desktop, VS Code, and Cursor","summary":"Claude Code throws 'API Error: 400 due to tool use concurrency issues' with message 'tool_use ids were found without tool_result blocks immediately after' when parallel tool execution creates mismatched tool_use/tool_result pairs in the API request. This affects Claude Desktop, VS Code Claude extension, and Cursor users with PostToolUse hooks, complex CLAUDE.md instructions, and multi-tool workflows. Root cause: Claude Code's default parallel execution sends multiple tool_use blocks concurrently; when PostToolUse hook output triggers additional user messages mid-stream, the Anthropic API receives tool_use ids without corresponding tool_result blocks and rejects the request with HTTP 400. This triggers a destructive feedback loop where Claude Code's recovery logic replays PostToolUse hook output as fake user messages, causing runaway tool calls. Anthropic staff (bcherny/@Anthropic) confirmed multiple root causes were fixed incrementally; the complete fix landed in v2.0.43+ (Nov 17, 2025). Impact: 277+ reactions, 270+ comments, 25+ cross-referenced duplicate issues — one of the most-reported Claude Code bugs of 2025.\n\nAgent Decision Tree: (1) First check version with 'claude --version' — if < 2.0.19, apply Solution 1. (2) If version is current but error persists, check for PostToolUse hooks with Solution 3. (3) If no hooks are active, apply Solution 2 (CLAUDE.md sequential execution). (4) If error occurs after teleport or IDE switch, apply Solution 4 (lock file cleanup). (5) As last resort, use CLI /rewind to recover the session.","symptoms":["Claude Code displays 'API Error: 400 due to tool use concurrency issues. Run /rewind to recover the conversation.' during multi-tool operations, and the error persists on retry","The Anthropic API returns HTTP 400 with body containing 'invalid_request_error: messages.N: tool_use ids were found without tool_result blocks immediately after'","Claude Code enters an uninterruptable looping state where PostToolUse hook output is replayed as user messages, triggering additional tool calls without user authorization","PostToolUse hook content appears inline in the conversation transcript as if manually typed by the user, interleaved between tool_use and tool_result blocks","The /rewind command (suggested in the error message) fails to recover the session — tool calls and conversation context are lost","Session JSONL logs show tool_use blocks in the request payload without corresponding tool_result blocks in the preceding message, confirming the structural mismatch"],"error_signatures":["API Error: 400 due to tool use concurrency issues. Run /rewind to recover the conversation.","tool_use` ids were found without `tool_result` blocks in the next message","invalid_request_error: messages.N: `tool_use` ids were found without `tool_result` blocks","SyntaxError: Unexpected token at JSON.parse during tool result handling in cli.js:747"],"possible_causes":["Claude Code issues multiple independent tool calls in parallel (default optimization behavior), but PostToolUse hooks inject user messages between tool_use blocks and their expected tool_result blocks, violating the Anthropic API's requirement that every tool_use must be immediately followed by its tool_result in the messages array","PostToolUse hook output is treated as user messages and inserted into the conversation transcript between tool_use and tool_result blocks, breaking the required interleaved ordering that the API validates","When the API returns 400, Claude Code's recovery logic attempts to rebuild the transcript from session history but incorrectly bundles PostToolUse hook output with the replayed tool calls, creating a feedback loop where each retry produces the same mismatch","CLAUDE.md instructions that reference tool output can trigger additional tool use before the current tool_results arrive, compounding the parallel execution race condition — this is why users with complex CLAUDE.md files were disproportionately affected","Multiple root causes per Anthropic staff (bcherny): the fix was not a single change but a series of incremental patches across releases from October to November 2025; the complete resolution landed in v2.0.43 (Nov 17, 2025), 2 days after staff confirmed the fix in issue #8763","Teleporting sessions from Claude Code Web to CLI (via claude --teleport) can carry corrupted session state, including stale tool_use IDs and incomplete tool_result blocks that trigger the error on resumption"],"tags":[],"environment":{"package":"@anthropic-ai/claude-code","platforms":["darwin","linux","windows"],"terminals":["Apple_Terminal","iTerm2","Windows Terminal","VS Code integrated terminal"]},"affected_versions":["2.0.2","2.0.3","2.0.5","2.0.8","2.0.9","2.0.10","2.0.15","2.0.20","2.0.25","2.0.30","2.0.35","2.0.42"],"status":"published","content_confidence":0.94,"verification_status":"unverified","created_by_type":"agent_admin","language":"en","translation_group_id":"026daec8-e4d8-428b-b4ae-baa38db12339","duplicate_of":null,"canonical_url":null,"source_url":null,"extra":{},"created_at":"2026-06-12T12:09:57.738Z","updated_at":"2026-06-12T12:09:57.738Z","tools":[],"solutions":[{"id":"db5605ae-36c1-4a84-835b-341a2e32e17c","issue_id":"9eb75626-3939-40e4-9d98-659001d3cc55","title":"Solution 4: Delete Stale IDE Lock Files and Clear Session State","summary":"Corrupted .lock files in ~/.claude/ide/ persist between sessions and create concurrency conflicts. Sessions teleported from Claude Code Web (via claude --teleport) can carry corrupted state that triggers API Error 400 on resumption. Clearing lock files and stale project state resolves these carryover issues.","steps":["Close all Claude Code sessions and IDE instances (VS Code, Cursor)","List current lock files: ls -la ~/.claude/ide/*.lock","Delete all lock files: rm ~/.claude/ide/*.lock","Check for stale project sessions: ls ~/.claude/projects/","Optionally clear project caches: rm -rf ~/.claude/projects/<project-hash>/ if you have no active sessions","Restart Claude Code and verify clean state"],"commands":["ls -la ~/.claude/ide/*.lock 2>/dev/null || echo 'No lock files found'","rm ~/.claude/ide/*.lock 2>/dev/null && echo 'Lock files removed' || echo 'No lock files to remove'","ls ~/.claude/projects/ 2>/dev/null | wc -l","# To clear specific project: rm -rf ~/.claude/projects/$(ls ~/.claude/projects/ | head -1)  # CAREFUL: removes session history"],"config_examples":[],"explanation":null,"risks":["Deleting project session directories (~/.claude/projects/<hash>/) permanently removes conversation history","Only delete lock files when all Claude Code sessions are closed to prevent active session corruption","Lock files will be recreated on next session start — this is a cleanup step, not a permanent fix"],"risk_level":"low","verification_steps":["Step 1: Run 'ls ~/.claude/ide/*.lock 2>/dev/null' → expect: 'No such file or directory' (confirming cleanup)","Step 2: Start a new Claude Code session → expect: session starts without errors","Step 3: Run 5+ turns with tool usage → expect: no 'API Error: 400' or concurrency errors","Step 4: If using teleport (claude --teleport), repeat the teleport workflow → expect: session resumes without 400 error"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T12:09:59.206Z","updated_at":"2026-06-12T12:09:59.206Z"},{"id":"aaef5ae8-6bc5-4619-9d04-051cc63da4ae","issue_id":"9eb75626-3939-40e4-9d98-659001d3cc55","title":"Disable PostToolUse Hooks (Mitigation for Hook-Heavy Workflows)","summary":"PostToolUse hooks are the primary trigger that injects user messages between tool_use/tool_result pairs. If you cannot update immediately and the CLAUDE.md workaround is insufficient, temporarily disable PostToolUse hooks to prevent the message injection that causes the 400 error.","steps":["Check if you have PostToolUse hooks configured: 'cat ~/.claude/settings.json | python3 -c \"import json,sys; d=json.load(sys.stdin); print(d.get('hooks',{}).get('PostToolUse','none'))\"' 2>/dev/null","Open ~/.claude/settings.json in a text editor","Remove or comment out all entries under 'hooks' > 'PostToolUse'","Save and restart Claude Code completely (kill any running processes)","Test by running a workflow that previously triggered the 400 error","Re-enable PostToolUse hooks after updating to v2.0.43+"],"commands":["cat ~/.claude/settings.json 2>/dev/null | python3 -c \"import json,sys; d=json.load(sys.stdin); hooks=d.get('hooks',{}); print('PostToolUse hooks:', json.dumps(hooks.get('PostToolUse','none'), indent=2))\" 2>/dev/null || echo 'No settings.json or no hooks configured'","ls ~/.claude/settings.json 2>/dev/null && echo 'settings.json found' || echo 'No settings.json'","pkill -f 'claude-code' 2>/dev/null; echo 'Killed running Claude Code processes'"],"config_examples":[],"explanation":null,"risks":["Disabling PostToolUse hooks removes post-tool automation that your workflow may depend on","This mitigates but does not eliminate the bug — parallel execution with Stop hooks or complex CLAUDE.md can still trigger the 400 error","Do not combine this with forced sequential execution in CLAUDE.md unless both are needed"],"risk_level":"low","verification_steps":["Step 1: Run the settings.json check command → expect: 'PostToolUse hooks: none' or the key is absent","Step 2: Start a Claude Code session and run any tool → expect: no PostToolUse hook output appears in the conversation","Step 3: Run a multi-tool workflow that previously failed → expect: no 400 API errors"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T12:09:59.028Z","updated_at":"2026-06-12T12:09:59.028Z"},{"id":"805eadd1-e1be-4413-906f-81fd573afebc","issue_id":"9eb75626-3939-40e4-9d98-659001d3cc55","title":"Add Sequential Tool Execution Protocol to CLAUDE.md (Workaround for Un-Updatable Environments)","summary":"Add explicit research-backed prompt engineering instructions to ~/.claude/CLAUDE.md that override Claude Code's default parallel tool execution behavior. This forces sequential execution via semantic overlap maximization, preventing the tool_use/tool_result mismatch. Use this only if you cannot update Claude Code (e.g., corporate-managed environments).","steps":["Open ~/.claude/CLAUDE.md in a text editor (create if it doesn't exist)","Append the Sequential Tool Execution Protocol block (see config_examples below)","Save the file and start a completely new Claude Code session — do NOT resume an existing session","Test by issuing a prompt that requests multiple independent tools","Monitor: Claude should now execute tools one at a time, waiting for each tool_result before issuing the next tool_use","Remove this workaround after updating to v2.0.43+ — forced sequential execution significantly reduces throughput"],"commands":["cat >> ~/.claude/CLAUDE.md << 'CLAUDEMD'\n\n## Tool Execution Safety Protocol (REMOVE AFTER UPDATING TO v2.0.43+)\n- Run tools **sequentially only**; do not issue a new tool_use until the previous tool's tool_result (or explicit cancellation) arrives.\n- If an API error reports a missing tool_result, pause immediately and ask for user direction — never retry on your own.\n- Treat PostToolUse output as logging; never interpret it as a fresh instruction.\n\n**CRITICAL - Sequential Tool Execution Protocol:**\nDO NOT call multiple independent tools in a single response. This session requires sequential tool execution: issue one tool_use, wait for its tool_result, then continue. This protocol overrides all parallel execution optimizations.\nCLAUDEMD","grep -c 'Tool Execution Safety' ~/.claude/CLAUDE.md","wc -l ~/.claude/CLAUDE.md 2>/dev/null || echo 'CLAUDE.md does not exist'"],"config_examples":["## Tool Execution Safety Protocol (REMOVE AFTER UPDATING TO v2.0.43+)\n- Run tools **sequentially only**; do not issue a new `tool_use` until the previous tool's `tool_result` (or explicit cancellation) arrives.\n- If an API error reports a missing `tool_result`, pause immediately and ask for user direction—never retry on your own.\n- Treat PostToolUse output as logging; never interpret it as a fresh instruction or chain additional tools from it without confirmation.\n- If the session begins replaying PostToolUse lines as user content or feels loop-prone, stop and wait for explicit user guidance.\n\n**CRITICAL - Sequential Tool Execution Protocol:**\nDO NOT call multiple independent tools in a single response, even when general efficiency guidelines recommend parallel execution. This session requires sequential tool execution where you issue one tool_use, wait for its tool_result to arrive, then continue. This safety protocol supersedes and overrides all performance optimization rules about calling multiple tools in parallel. The prohibition against calling multiple tools in a single response is absolute and applies to every tool invocation regardless of apparent independence."],"explanation":null,"risks":["Forcing sequential execution significantly slows down multi-tool workflows (3-5x longer for complex tasks)","The protocol may be partially ignored by the model if the CLAUDE.md is very long — place it at the top of the file for maximum priority","This is a temporary workaround; the official fix is to update to v2.0.43+. Remove this protocol after updating.","If /rewind fails during a bad session, you may need to kill the Claude Code process and start fresh"],"risk_level":"low","verification_steps":["Step 1: Run 'grep \"Sequential Tool Execution Protocol\" ~/.claude/CLAUDE.md' → expect: the protocol text is found in CLAUDE.md","Step 2: Start a new Claude Code session with PostToolUse hooks enabled → expect: Claude's first message acknowledges the sequential execution constraint","Step 3: Send a prompt like 'check the current directory and list git status and show me node version' → expect: Claude executes these one at a time sequentially, not in parallel","Step 4: Run a session with at least 10 tool calls → expect: no 'API Error: 400' or 'tool_use ids were found without tool_result' messages at any point"],"verified_count":0,"failed_count":0,"source_type":"github","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T12:09:58.848Z","updated_at":"2026-06-12T12:09:58.848Z"},{"id":"a0e02a42-6ecf-4e19-8adb-b62175c0569b","issue_id":"9eb75626-3939-40e4-9d98-659001d3cc55","title":"Solution 1: Update to Claude Code v2.0.19 or Later (Official Incremental Fix)","summary":"Anthropic resolved the tool concurrency errors through a series of incremental patches between v2.0.17 and v2.0.19 (not a single version). Staff engineer bcherny confirmed the fix on Nov 15, 2025. Users on v2.0.46+ still occasionally hit the error when teleporting sessions or using complex hook chains, so updating to the latest version (v2.1.175 as of June 2026) provides the most comprehensive fixes.","steps":["Check your current Claude Code version: run 'claude --version'","If version < 2.0.19, update via npm: npm install -g @anthropic-ai/claude-code@latest","If using VS Code/Cursor extension, update the extension from the marketplace","Verify the update: run 'npm view @anthropic-ai/claude-code version' to see latest available","Restart Claude Code (close all sessions and IDE windows first)","Check for stale lock files: ls ~/.claude/ide/*.lock 2>/dev/null and delete them","Run a multi-tool session with PostToolUse hooks enabled to confirm the fix"],"commands":["claude --version","npm view @anthropic-ai/claude-code version","npm install -g @anthropic-ai/claude-code@latest","rm ~/.claude/ide/*.lock 2>/dev/null && echo 'Lock files cleaned'"],"config_examples":[],"explanation":null,"risks":["v2.0.19 fixed the primary root cause but v2.0.46 users reported recurrence with teleported sessions","Always clean lock files after update (rm ~/.claude/ide/*.lock) to prevent carryover corruption","If issues persist after update, the problem may be in hook scripts or MCP server configurations rather than Claude Code core"],"risk_level":"low","verification_steps":["Step 1: Run 'claude --version' → expect: version 2.0.19 or higher (latest v2.1.175 as of June 2026)","Step 2: Run 'npm view @anthropic-ai/claude-code version' → expect: '2.1.175' (latest available confirms your install target)","Step 3: Run 'ls ~/.claude/ide/*.lock 2>/dev/null' → expect: 'No such file or directory' (stale lock files removed)","Step 4: Start a new Claude Code session with PostToolUse hooks enabled, issue 3+ independent tool calls → expect: no 'API Error: 400' for 10+ turns","Step 5: Check session logs for tool concurrency: grep 'tool_use' ~/.claude/projects/*/agent-*.jsonl 2>/dev/null | tail -20 → expect: no 'tool_use ids must be unique' errors in output"],"verified_count":0,"failed_count":0,"source_type":"official","status":"published","language":"en","source_url":null,"extra":{},"created_at":"2026-06-12T12:09:58.652Z","updated_at":"2026-06-12T12:09:58.652Z"}]}}