spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

docs: Add bug report for duplicate tool_result blocks issueBrowse files
Documents API error where multiple tool_result blocks are sent with
the same tool_use_id when a tool fails. The "Sibling tool call errored"
message is incorrectly being sent for the same tool that failed,
rather than only for other sibling tools in a parallel batch.

Includes:
- Root cause analysis
- Example JSON from reported incidents
- Suggested fix locations and pseudocode
- Related request IDs for debugging
Claude authored on Dec 8, 2025 parent de49a07 · commit 20c5837683b0
1 changed file+123 -0compared with de49a07
A.github/issues/duplicate-tool-result-bug.md
@@ -1,0 +1,123 @@
1+# Bug Report: Duplicate tool_result blocks with same tool_use_id
2+
3+## Summary
4+When a tool call fails (particularly observed with the Tmux tool), two `tool_result` blocks are incorrectly sent to the API with the same `tool_use_id`, causing an API error:
5+
6+```
7+API Error: 400
8+{"type":"error","error":{"type":"invalid_request_error","message":"messages.X.content.1: each tool_use must have a single result. Found multiple `tool_result` blocks with id: toolu_XXX"}}
9+```
10+
11+## Root Cause
12+The parallel tool execution error handling code sends a "Sibling tool call errored" message even for the tool that actually failed, when it should only send this message for OTHER sibling tools in the parallel batch.
13+
14+## Reproduction
15+1. Execute a tool call that will fail (e.g., Tmux select-pane on a non-existent window)
16+2. Observe two tool_result messages being generated:
17+ - First: The actual error result ("Window not found...")
18+ - Second: A "<tool_use_error>Sibling tool call errored</tool_use_error>" message with the SAME tool_use_id
19+
20+## Example JSON (from reported incident)
21+```json
22+// Assistant requests tool use
23+{
24+ "type": "tool_use",
25+ "id": "toolu_01K2K2KFvUrwA9PaHGp652zW",
26+ "name": "Tmux",
27+ "input": {"args": ["select-pane", "-t", "test-perms3:0.0"]}
28+}
29+
30+// First tool_result (correct - actual error)
31+{
32+ "type": "user",
33+ "message": {
34+ "role": "user",
35+ "content": [{
36+ "tool_use_id": "toolu_01K2K2KFvUrwA9PaHGp652zW",
37+ "type": "tool_result",
38+ "content": "Window not found. The specified window may not exist.",
39+ "is_error": true
40+ }]
41+ }
42+}
43+
44+// Second tool_result (BUG - same tool_use_id!)
45+{
46+ "type": "user",
47+ "message": {
48+ "role": "user",
49+ "content": [{
50+ "type": "tool_result",
51+ "content": "<tool_use_error>Sibling tool call errored</tool_use_error>",
52+ "is_error": true,
53+ "tool_use_id": "toolu_01K2K2KFvUrwA9PaHGp652zW"
54+ }]
55+ }
56+}
57+```
58+
59+## Expected Behavior
60+- When a tool fails, only ONE tool_result should be sent for that tool_use_id
61+- The "Sibling tool call errored" message should ONLY be sent for OTHER tool_use_ids in a parallel batch, not for the tool that actually errored
62+
63+## Suggested Fix Location
64+The fix should be in the code that handles parallel tool execution errors:
65+
66+```typescript
67+// Pseudocode for the fix
68+function handleParallelToolResults(toolUseIds: string[], failedToolId: string, error: Error) {
69+ const results = [];
70+
71+ for (const id of toolUseIds) {
72+ if (id === failedToolId) {
73+ // Send actual error for the failed tool
74+ results.push({
75+ tool_use_id: id,
76+ type: "tool_result",
77+ content: error.message,
78+ is_error: true
79+ });
80+ } else {
81+ // Only send sibling error for OTHER tools
82+ results.push({
83+ tool_use_id: id,
84+ type: "tool_result",
85+ content: "<tool_use_error>Sibling tool call errored</tool_use_error>",
86+ is_error: true
87+ });
88+ }
89+ }
90+
91+ return results;
92+}
93+```
94+
95+Additionally, a deduplication check before sending to the API would prevent this:
96+```typescript
97+function deduplicateToolResults(messages: Message[]): Message[] {
98+ const seenToolUseIds = new Set<string>();
99+ return messages.filter(msg => {
100+ if (msg.type === "tool_result") {
101+ if (seenToolUseIds.has(msg.tool_use_id)) {
102+ return false; // Skip duplicate
103+ }
104+ seenToolUseIds.add(msg.tool_use_id);
105+ }
106+ return true;
107+ });
108+}
109+```
110+
111+## Related CHANGELOG Fixes
112+Similar issues have been fixed before:
113+- v1.0.84: "Fix tool_use/tool_result id mismatch error when network is unstable"
114+- v2.0.0: "Hooks: Reduced PostToolUse 'tool_use' ids were found without 'tool_result' blocks errors"
115+- v2.0.22: "Fix bug causing duplicate permission prompts with parallel tool calls"
116+
117+## Reported By
118+Issue reported via Slack with multiple reproductions showing the Tmux tool triggering this bug.
119+
120+## Request IDs (for debugging)
121+- req_011CVt2KXhCGmrL2YN9sSZQP
122+- req_011CVtFYJLPxn9oB9FEkCnRr
123+- req_011CVtG1PREveTLikakXGEdn