Compare commits

..

1 Commits

Author SHA1 Message Date
Claude
20c5837683 docs: Add bug report for duplicate tool_result blocks issue
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
2025-12-08 01:19:25 +00:00
5 changed files with 170 additions and 225 deletions

View File

@@ -0,0 +1,123 @@
# Bug Report: Duplicate tool_result blocks with same tool_use_id
## Summary
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:
```
API Error: 400
{"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"}}
```
## Root Cause
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.
## Reproduction
1. Execute a tool call that will fail (e.g., Tmux select-pane on a non-existent window)
2. Observe two tool_result messages being generated:
- First: The actual error result ("Window not found...")
- Second: A "<tool_use_error>Sibling tool call errored</tool_use_error>" message with the SAME tool_use_id
## Example JSON (from reported incident)
```json
// Assistant requests tool use
{
"type": "tool_use",
"id": "toolu_01K2K2KFvUrwA9PaHGp652zW",
"name": "Tmux",
"input": {"args": ["select-pane", "-t", "test-perms3:0.0"]}
}
// First tool_result (correct - actual error)
{
"type": "user",
"message": {
"role": "user",
"content": [{
"tool_use_id": "toolu_01K2K2KFvUrwA9PaHGp652zW",
"type": "tool_result",
"content": "Window not found. The specified window may not exist.",
"is_error": true
}]
}
}
// Second tool_result (BUG - same tool_use_id!)
{
"type": "user",
"message": {
"role": "user",
"content": [{
"type": "tool_result",
"content": "<tool_use_error>Sibling tool call errored</tool_use_error>",
"is_error": true,
"tool_use_id": "toolu_01K2K2KFvUrwA9PaHGp652zW"
}]
}
}
```
## Expected Behavior
- When a tool fails, only ONE tool_result should be sent for that tool_use_id
- 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
## Suggested Fix Location
The fix should be in the code that handles parallel tool execution errors:
```typescript
// Pseudocode for the fix
function handleParallelToolResults(toolUseIds: string[], failedToolId: string, error: Error) {
const results = [];
for (const id of toolUseIds) {
if (id === failedToolId) {
// Send actual error for the failed tool
results.push({
tool_use_id: id,
type: "tool_result",
content: error.message,
is_error: true
});
} else {
// Only send sibling error for OTHER tools
results.push({
tool_use_id: id,
type: "tool_result",
content: "<tool_use_error>Sibling tool call errored</tool_use_error>",
is_error: true
});
}
}
return results;
}
```
Additionally, a deduplication check before sending to the API would prevent this:
```typescript
function deduplicateToolResults(messages: Message[]): Message[] {
const seenToolUseIds = new Set<string>();
return messages.filter(msg => {
if (msg.type === "tool_result") {
if (seenToolUseIds.has(msg.tool_use_id)) {
return false; // Skip duplicate
}
seenToolUseIds.add(msg.tool_use_id);
}
return true;
});
}
```
## Related CHANGELOG Fixes
Similar issues have been fixed before:
- v1.0.84: "Fix tool_use/tool_result id mismatch error when network is unstable"
- v2.0.0: "Hooks: Reduced PostToolUse 'tool_use' ids were found without 'tool_result' blocks errors"
- v2.0.22: "Fix bug causing duplicate permission prompts with parallel tool calls"
## Reported By
Issue reported via Slack with multiple reproductions showing the Tmux tool triggering this bug.
## Request IDs (for debugging)
- req_011CVt2KXhCGmrL2YN9sSZQP
- req_011CVtFYJLPxn9oB9FEkCnRr
- req_011CVtG1PREveTLikakXGEdn

View File

@@ -1,118 +1,5 @@
# Changelog
## 2.0.73
- Added clickable `[Image #N]` links that open attached images in the default viewer
- Added alt-y yank-pop to cycle through kill ring history after ctrl-y yank
- Added search filtering to the plugin discover screen (type to filter by name, description, or marketplace)
- Added support for custom session IDs when forking sessions with `--session-id` combined with `--resume` or `--continue` and `--fork-session`
- Fixed slow input history cycling and race condition that could overwrite text after message submission
- Improved `/theme` command to open theme picker directly
- Improved theme picker UI
- Improved search UX across resume session, permissions, and plugins screens with a unified SearchBox component
- [VSCode] Added tab icon badges showing pending permissions (blue) and unread completions (orange)
## 2.0.72
- Added Claude in Chrome (Beta) feature that works with the Chrome extension (https://claude.ai/chrome) to let you control your browser directly from Claude Code
- Reduced terminal flickering
- Added scannable QR code to mobile app tip for quick app downloads
- Added loading indicator when resuming conversations for better feedback
- Fixed `/context` command not respecting custom system prompts in non-interactive mode
- Fixed order of consecutive Ctrl+K lines when pasting with Ctrl+Y
- Improved @ mention file suggestion speed (~3x faster in git repositories)
- Improved file suggestion performance in repos with `.ignore` or `.rgignore` files
- Improved settings validation errors to be more prominent
- Changed thinking toggle from Tab to Alt+T to avoid accidental triggers
## 2.0.71
- Added /config toggle to enable/disable prompt suggestions
- Added `/settings` as an alias for the `/config` command
- Fixed @ file reference suggestions incorrectly triggering when cursor is in the middle of a path
- Fixed MCP servers from `.mcp.json` not loading when using `--dangerously-skip-permissions`
- Fixed permission rules incorrectly rejecting valid bash commands containing shell glob patterns (e.g., `ls *.txt`, `for f in *.png`)
- Bedrock: Environment variable `ANTHROPIC_BEDROCK_BASE_URL` is now respected for token counting and inference profile listing
- New syntax highlighting engine for native build
## 2.0.70
- Added Enter key to accept and submit prompt suggestions immediately (tab still accepts for editing)
- Added wildcard syntax `mcp__server__*` for MCP tool permissions to allow or deny all tools from a server
- Added auto-update toggle for plugin marketplaces, allowing per-marketplace control over automatic updates
- Added `current_usage` field to status line input, enabling accurate context window percentage calculations
- Fixed input being cleared when processing queued commands while the user was typing
- Fixed prompt suggestions replacing typed input when pressing Tab
- Fixed diff view not updating when terminal is resized
- Improved memory usage by 3x for large conversations
- Improved resolution of stats screenshots copied to clipboard (Ctrl+S) for crisper images
- Removed # shortcut for quick memory entry (tell Claude to edit your CLAUDE.md instead)
- Fix thinking mode toggle in /config not persisting correctly
- Improve UI for file creation permission dialog
## 2.0.69
- Minor bugfixes
## 2.0.68
- Fixed IME (Input Method Editor) support for languages like Chinese, Japanese, and Korean by correctly positioning the composition window at the cursor
- Fixed a bug where disallowed MCP tools were visible to the model
- Fixed an issue where steering messages could be lost while a subagent is working
- Fixed Option+Arrow word navigation treating entire CJK (Chinese, Japanese, Korean) text sequences as a single word instead of navigating by word boundaries
- Improved plan mode exit UX: show simplified yes/no dialog when exiting with empty or missing plan instead of throwing an error
- Add support for enterprise managed settings. Contact your Anthropic account team to enable this feature.
## 2.0.67
- Thinking mode is now enabled by default for Opus 4.5
- Thinking mode configuration has moved to /config
- Added search functionality to `/permissions` command with `/` keyboard shortcut for filtering rules by tool name
- Show reason why autoupdater is disabled in `/doctor`
- Fixed false "Another process is currently updating Claude" error when running `claude update` while another instance is already on the latest version
- Fixed MCP servers from `.mcp.json` being stuck in pending state when running in non-interactive mode (`-p` flag or piped input)
- Fixed scroll position resetting after deleting a permission rule in `/permissions`
- Fixed word deletion (opt+delete) and word navigation (opt+arrow) not working correctly with non-Latin text such as Cyrillic, Greek, Arabic, Hebrew, Thai, and Chinese
- Fixed `claude install --force` not bypassing stale lock files
- Fixed consecutive @~/ file references in CLAUDE.md being incorrectly parsed due to markdown strikethrough interference
- Windows: Fixed plugin MCP servers failing due to colons in log directory paths
## 2.0.65
- Added ability to switch models while writing a prompt using alt+p (linux, windows), option+p (macos).
- Added context window information to status line input
- Added `fileSuggestion` setting for custom `@` file search commands
- Added `CLAUDE_CODE_SHELL` environment variable to override automatic shell detection (useful when login shell differs from actual working shell)
- Fixed prompt not being saved to history when aborting a query with Escape
- Fixed Read tool image handling to identify format from bytes instead of file extension
## 2.0.64
- Made auto-compacting instant
- Agents and bash commands can run asynchronously and send messages to wake up the main agent
- /stats now provides users with interesting CC stats, such as favorite model, usage graph, usage streak
- Added named session support: use `/rename` to name sessions, `/resume <name>` in REPL or `claude --resume <name>` from the terminal to resume them
- Added support for .claude/rules/`. See https://code.claude.com/docs/en/memory for details.
- Added image dimension metadata when images are resized, enabling accurate coordinate mappings for large images
- Fixed auto-loading .env when using native installer
- Fixed `--system-prompt` being ignored when using `--continue` or `--resume` flags
- Improved `/resume` screen with grouped forked sessions and keyboard shortcuts for preview (P) and rename (R)
- VSCode: Added copy-to-clipboard button on code blocks and bash tool inputs
- VSCode: Fixed extension not working on Windows ARM64 by falling back to x64 binary via emulation
- Bedrock: Improve efficiency of token counting
- Bedrock: Add support for `aws login` AWS Management Console credentials
- Unshipped AgentOutputTool and BashOutputTool, in favor of a new unified TaskOutputTool
## 2.0.62
- Added "(Recommended)" indicator for multiple-choice questions, with the recommended option moved to the top of the list
- Added `attribution` setting to customize commit and PR bylines (deprecates `includeCoAuthoredBy`)
- Fixed duplicate slash commands appearing when ~/.claude is symlinked to a project directory
- Fixed slash command selection not working when multiple commands share the same name
- Fixed an issue where skill files inside symlinked skill directories could become circular symlinks
- Fixed running versions getting removed because lock file incorrectly going stale
- Fixed IDE diff tab not closing when rejecting file changes
## 2.0.61
- Reverted VSCode support for multiple terminal clients due to responsiveness issues.

View File

@@ -1,64 +0,0 @@
# Bug Report: /hooks command always selects PreToolUse on first attempt
## Summary
When using the `/hooks` command to create a new hook, the hook type selector always selects `PreToolUse` on the first attempt, regardless of which option the user scrolls to and selects with Enter. The selection works correctly on subsequent attempts after pressing Escape.
## Steps to Reproduce
1. Open Claude Code
2. Type `/hooks` to open the hooks management interface
3. Navigate to create a new hook
4. When the hook type selector appears (showing PreToolUse, PostToolUse, Stop, UserPromptSubmit, etc.), scroll down using arrow keys to select a different hook type (e.g., `PostToolUse`)
5. Press Enter to confirm selection
6. **Bug:** `PreToolUse` is selected instead of the highlighted option
## Workaround
1. Press Escape to cancel the selection
2. Re-enter the hook type selector
3. Scroll to desired hook type
4. Press Enter
5. **Result:** Correct hook type is now selected
## Expected Behavior
The hook type selector should select the option that is visually highlighted when the user presses Enter, on both first and subsequent attempts.
## Root Cause Analysis
This appears to be a **state synchronization issue** where:
1. On first render of the hook type selector, the internal selected index is initialized to `0` (PreToolUse is the first item)
2. The visual highlight updates correctly when scrolling with arrow keys (the user sees a different item highlighted)
3. However, when pressing Enter, the handler reads from the internal state (which may still be `0`) rather than the current highlighted position
4. After pressing Escape and re-opening the selector, the state is properly synchronized
### Potential Code Areas
Based on similar issues and the CHANGELOG history, the fix likely involves one of these patterns:
1. **Initial state not synced**: The selection state may need to be initialized differently, or there's a race condition between render and state initialization
2. **Event handler reading stale state**: The Enter key handler might be using a captured/stale reference to the selection index rather than the current value
3. **Scroll handler not updating state**: The arrow key navigation might only be updating the visual highlight without updating the underlying state that Enter reads from
### Similar Fixed Issues
- **CHANGELOG v2.0.35**: "Fixed menu navigation getting stuck on items with empty string or other falsy values (e.g., in the `/hooks` menu)"
- **CHANGELOG v0.2.69**: "Fixed UI glitches with improved Select component behavior"
- **Issue #6674**: Hook Navigation Infinite Loop on Duplicate Entries (related Select component issue)
## Environment
- Reported on: Multiple environments
- Claude Code Version: Current latest
## Slack Thread Reference
https://anthropic.slack.com/archives/C07VBSHV7EV/p1766159670734839?thread_ts=1766158844.979909&cid=C07VBSHV7EV
## Labels
`bug`, `hooks`, `ui`, `select-component`

View File

@@ -22,29 +22,23 @@ Performs automated code review on a pull request using multiple specialized agen
- **Agent #4**: Analyze git blame/history for context-based issues
5. Scores each issue 0-100 for confidence level
6. Filters out issues below 80 confidence threshold
7. Outputs review (to terminal by default, or as PR comment with `--comment` flag)
7. Posts review comment with high-confidence issues only
**Usage:**
```bash
/code-review [--comment]
/code-review
```
**Options:**
- `--comment`: Post the review as a comment on the pull request (default: outputs to terminal only)
**Example workflow:**
```bash
# On a PR branch, run locally (outputs to terminal):
# On a PR branch, run:
/code-review
# Post review as PR comment:
/code-review --comment
# Claude will:
# - Launch 4 review agents in parallel
# - Score each issue for confidence
# - Output issues ≥80 confidence (to terminal or PR depending on flag)
# - Skip if no high-confidence issues found
# - Post comment with issues ≥80 confidence
# - Skip posting if no high-confidence issues found
```
**Features:**
@@ -120,23 +114,17 @@ This plugin is included in the Claude Code repository. The command is automatica
### Standard PR review workflow:
```bash
# Create PR with changes
# Run local review (outputs to terminal)
/code-review
# Review the automated feedback
# Make any necessary fixes
# Optionally post as PR comment
/code-review --comment
# Merge when ready
```
### As part of CI/CD:
```bash
# Trigger on PR creation or update
# Use --comment flag to post review comments
/code-review --comment
# Automatically posts review comments
# Skip if review already exists
```

View File

@@ -1,5 +1,5 @@
---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr list:*), mcp__github_inline_comment__create_inline_comment
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh pr comment:*), Bash(gh pr diff:*), Bash(gh pr view:*), Bash(gh pr list:*)
description: Code review a pull request
---
@@ -11,7 +11,7 @@ To do this, follow these steps precisely:
- The pull request is closed
- The pull request is a draft
- The pull request does not need code review (e.g. automated PR, trivial change that is obviously correct)
- Claude has already commented on this PR (check `gh pr view <PR> --comments` for comments left by claude)
- You have already submitted a code review on this pull request
If any condition is true, stop and do not proceed.
@@ -52,30 +52,12 @@ Note: Still review Claude generated PR's.
6. Filter out any issues that were not validated in step 5. This step will give us our list of high signal issues for our review.
7. If issues were found, skip to step 8 to post inline comments directly.
If NO issues were found, post a summary comment using `gh pr comment` (if `--comment` argument is provided):
"No issues found. Checked for bugs and CLAUDE.md compliance."
8. Post inline comments for each issue using `mcp__github_inline_comment__create_inline_comment`:
- `path`: the file path
- `line` (and `startLine` for ranges): select the buggy lines so the user sees them
- `body`: Brief description of the issue (no "Bug:" prefix). For small fixes (up to 5 lines changed), include a committable suggestion:
```suggestion
corrected code here
```
**Suggestions must be COMPLETE.** If a fix requires additional changes elsewhere (e.g., renaming a variable requires updating all usages), do NOT use a suggestion block. The author should be able to click "Commit suggestion" and have a working fix - no followup work required.
For larger fixes (6+ lines, structural changes, or changes spanning multiple locations), do NOT use suggestion blocks. Instead:
1. Describe what the issue is
2. Explain the suggested fix at a high level
3. Include a copyable prompt for Claude Code that the user can use to fix the issue, formatted as:
```
Fix [file:line]: [brief description of issue and suggested fix]
```
**IMPORTANT: Only post ONE comment per unique issue. Do not post duplicate comments.**
7. Finally, comment on the pull request.
When writing your comment, follow these guidelines:
a. Keep your output brief
b. Avoid emojis
c. Link and cite relevant code, files, and URLs for each issue
d. When citing CLAUDE.md violations, you MUST quote the exact text from CLAUDE.md that is being violated (e.g., CLAUDE.md says: "Use snake_case for variable names")
Use this list when evaluating issues in Steps 4 and 5 (these are false positives, do NOT flag):
@@ -90,18 +72,47 @@ Notes:
- Use gh CLI to interact with GitHub (e.g., fetch pull requests, create comments). Do not use web fetch.
- Create a todo list before starting.
- You must cite and link each issue in inline comments (e.g., if referring to a CLAUDE.md, include a link to it).
- If no issues are found, post a comment with the following format:
- You must cite and link each issue (e.g., if referring to a CLAUDE.md, include a link to it).
- For your final comment, follow the following format precisely (assuming for this example that you found 3 issues):
---
## Code review
No issues found. Checked for bugs and CLAUDE.md compliance.
Found 3 issues:
1. <brief description of bug> (CLAUDE.md says: "<exact quote from CLAUDE.md>")
<link to file and line with full sha1 + line range for context, eg. https://github.com/anthropics/claude-code/blob/1d54823877c4de72b2316a64032a54afc404e619/README.md#L13-L17>
2. <brief description of bug> (some/other/CLAUDE.md says: "<exact quote from CLAUDE.md>")
<link to file and line with full sha1 + line range for context>
3. <brief description of bug> (bug due to <file and code snippet>)
<link to file and line with full sha1 + line range for context>
🤖 Generated with [Claude Code](https://claude.ai/code)
<sub>- If this code review was useful, please react with 👍. Otherwise, react with 👎.</sub>
---
- When linking to code in inline comments, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
- Or, if you found no issues:
---
## Auto code review
No issues found. Checked for bugs and CLAUDE.md compliance.
🤖 Generated with [Claude Code](https://claude.ai/code)
---
- When linking to code, follow the following format precisely, otherwise the Markdown preview won't render correctly: https://github.com/anthropics/claude-code/blob/c21d3c10bc8e898b7ac1a2d745bdc9bc4e423afe/package.json#L10-L15
- Requires full git sha
- You must provide the full sha. Commands like `https://github.com/owner/repo/blob/$(git rev-parse HEAD)/foo/bar` will not work, since your comment will be directly rendered in Markdown.
- Repo name must match the repo you're code reviewing