Bug: Generic "Sibling Tool Call Errored" Replaces Actual MCP Error Messages

Resolved 💬 3 comments Opened Feb 14, 2026 by stevehockey Closed Feb 18, 2026

Bug Report: Generic "Sibling Tool Call Errored" Replaces Actual Error Messages

Product: Claude Code (CLI)
Component: MCP Client / Parallel Tool Execution Handler
Severity: Medium (UX Issue)
Reproducible: Yes (100%)

---

Summary

When multiple MCP tool calls are executed in parallel and one fails, subsequent tool calls display the generic error message "Error: Sibling tool call errored" instead of their actual error messages. This makes it impossible for users to diagnose issues without checking server logs.

---

Impact

User Experience:

  • Users cannot determine what went wrong without extensive debugging
  • Error messages are replaced with unhelpful generic text
  • Debugging time increases from ~2 minutes to 10+ minutes
  • Leads to support requests and confusion

Developer Experience:

  • MCP server developers craft detailed error messages that users never see
  • Proper JSON-RPC 2.0 error responses are discarded by Claude Code
  • No way to work around this behavior from the MCP server side

---

Steps to Reproduce

Prerequisites

  1. Any MCP server that returns errors (we tested with claude-memory MCP server)
  2. Claude Code CLI with MCP integration configured
  3. Test project with files that will trigger different error types

Reproduction Steps

  1. Configure MCP server in ~/.claude/config.json:
{
  "mcpServers": {
    "claude-memory": {
      "command": "claude-memory",
      "args": ["mcp"],
      "env": {}
    }
  }
}
  1. Create test files:
# Valid file
echo "package main" > main.go

# Valid file
echo "package utils" > utils.go

# Sensitive file (will trigger error)
echo "API_KEY=secret123" > .env
  1. Ask Claude to review all files in parallel:
User prompt: "Please review these files: main.go, utils.go, and .env"
  1. Observe the output

---

Expected Behavior

Each tool call should return its own specific error message:

⏺ ollama_review_file (file: "main.go")
  ⎿ ✅ Success: [review content]

⏺ ollama_review_file (file: "utils.go")
  ⎿ ✅ Success: [review content]

⏺ ollama_review_file (file: ".env")
  ⎿ ❌ Error: access to sensitive file denied: .env

---

Actual Behavior

The third tool call shows a generic error instead of its actual error:

⏺ ollama_review_file (file: "main.go")
  ⎿ ✅ Success: [review content]

⏺ ollama_review_file (file: ".env")
  ⎿ ❌ Error: access to sensitive file denied: .env

⏺ ollama_review_file (file: "utils.go")
  ⎿ ❌ Error: Sibling tool call errored   ← UNHELPFUL!

Note: The exact order may vary, but the pattern is consistent: when one parallel call fails, other calls show "Sibling tool call errored" instead of their actual status or error.

---

Technical Analysis

What the MCP Server Returns (Correct)

The MCP server returns a proper JSON-RPC 2.0 error response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "content": [{
      "type": "text",
      "text": "access to sensitive file denied: .env"
    }],
    "isError": true
  }
}

All MCP protocol requirements are met:

  • ✅ Proper JSON-RPC 2.0 structure
  • isError: true flag set
  • ✅ Error message in content[0].text
  • ✅ Logged to server logs correctly

What Claude Code Does (Problematic)

When executing parallel tool calls, Claude Code's internal handler appears to:

  1. Send all tool calls in parallel (correct)
  2. Receive responses from MCP server (correct)
  3. Detect that one call has isError: true
  4. Cancel remaining/pending calls (questionable)
  5. Replace actual errors with "Sibling tool call errored" (bug)

Hypothetical pseudocode (we don't have access to Claude Code source):

async function executeParallelTools(toolCalls) {
  const promises = toolCalls.map(call => executeTool(call));

  try {
    return await Promise.all(promises);
  } catch (firstError) {
    // BUG: When one fails, cancel others and replace errors
    cancelRemainingCalls();

    return promises.map((p, index) => {
      if (p.status === 'rejected' && p !== firstError) {
        return { error: "Sibling tool call errored" };  // ❌ Lost context!
      }
      return p;
    });
  }
}

---

Why This Is a Bug

1. Loss of Information

Actual error messages are replaced with a generic message that provides no actionable information.

2. Violates User Expectations

Users expect each tool call to report its own status independently, whether success, error, or cancellation.

3. Makes Debugging Impossible

Without the actual error message, users cannot:

  • Understand what went wrong
  • Take corrective action
  • Learn from mistakes
  • Self-serve without support

4. Breaks MCP Contract

The MCP server fulfills its contract by returning proper errors, but Claude Code discards them. This wastes developer effort and breaks the error communication chain.

---

Suggested Fix

Option 1: Don't Replace Errors (Preferred)

Each tool call should report its own actual error, even in parallel execution:

⏺ ollama_review_file (file: "main.go")
  ⎿ ✅ Success

⏺ ollama_review_file (file: ".env")
  ⎿ ❌ Error: access to sensitive file denied: .env

⏺ ollama_review_file (file: "utils.go")
  ⎿ ✅ Success   ← Show actual result, not "sibling errored"

If a call was actually cancelled, explain why:

⏺ ollama_review_file (file: "utils.go")
  ⎿ ⚠️ Cancelled: Previous tool call failed, remaining operations were cancelled

Option 2: Aggregate Errors

If cancellation is necessary, at least show the root cause:

⏺ Batch operation failed
  ⎿ ❌ ollama_review_file (file: ".env"): access to sensitive file denied
  ⎿ ⚠️ Remaining calls cancelled due to failure above

Option 3: Don't Cancel at All

Let all parallel calls complete independently. Users can handle multiple errors.

---

Workaround (For MCP Server Developers)

While this is a Claude Code bug, we are implementing a workaround in our MCP server:

Strategy: Structured Error Codes

We're adding error codes to our messages so they're traceable even when replaced:

Before: "access to sensitive file denied: .env"
After:  "[E0001] file_access: sensitive file denied: .env"

Why this helps:

  • If [E0001] appears before "sibling errored", users can look up the code
  • Error codes can be documented separately
  • Users can trace errors via logs
  • Better than nothing, but not a real fix

Limitations:

  • Users still see "Sibling tool call errored"
  • Still requires checking docs/logs
  • Only helps if users notice the error code
  • Doesn't fix the root cause

---

Test Case

We can provide a minimal reproducible test case if helpful:

  1. MCP Server: claude-memory (open source)
  1. Reproduction script:
# Setup
claude-memory init

# Trigger parallel calls with one error
# (exact prompt provided upon request)
  1. Expected vs Actual: Documented above

---

Additional Context

Related Issues:

  • MCP server developers lose visibility into error propagation
  • No way to debug without access to Claude Code internals
  • Impacts all MCP servers, not just claude-memory

User Reports:

  • Multiple users confused by "sibling errored" message
  • Debugging requires checking server logs (not user-friendly)
  • Creates support burden for MCP server maintainers

Our Tracking:

---

Environment

  • Claude Code Version: [Latest - please specify current version]
  • Operating System: macOS 14.x (also occurs on Linux)
  • MCP Server: claude-memory v5.2
  • MCP Protocol Version: 1.0

---

Severity Justification

Medium Severity because:

  • ✅ Not a crash or data loss
  • ✅ Workarounds exist (check logs, error codes)
  • ❌ Significantly degrades user experience
  • ❌ Affects all MCP servers with parallel operations
  • ❌ Makes self-service debugging nearly impossible

Could be High Severity if considering:

  • Impact on ecosystem (all MCP server developers)
  • User frustration and support burden
  • Violation of expected error propagation behavior

---

Request

Please fix Claude Code's parallel tool execution handler to:

  1. Preserve actual error messages from MCP servers
  2. Report each tool call's status independently
  3. If cancellation is required, explain why (don't use generic "sibling errored")
  4. Allow all calls to complete if possible (fail independently vs fail-fast)

This would eliminate the need for workarounds and restore proper error communication between MCP servers and users.

---

Contact

For questions or additional details:

---

Thank you for considering this bug report!

We're implementing error codes as a workaround, but would greatly prefer an upstream fix that benefits all MCP server developers and Claude Code users.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗