Cowork mode: hallucinated MCP tool name causes silent SDK deadlock until manual restart

Resolved 💬 3 comments Opened Apr 27, 2026 by JesperLive Closed May 1, 2026

Summary

In Claude Desktop Cowork mode, when the model emits a tool_use block with a tool name that does not exist in the loaded MCP tool schema (concrete example below: mcp__Desktop_Commander__lines, when the Desktop Commander MCP has no lines tool), the Agent SDK holds the tool-use frame open indefinitely instead of returning a tool-not-found error. The session appears "thinking" forever with no in-band recovery path. The user must kill the host process to break the deadlock.

Environment

  • Claude Desktop (Cowork mode) on Windows 11
  • Model: claude-opus-4-7 (advertised in env)
  • Claude Code binary: 2.1.111 and 2.1.119
  • Desktop Commander MCP: v0.2.39
  • Encountered 2026-04-27, session id local_04615dc0-2f23-4ac1-a07a-a4906c8dab84, CLI session 5410d741-ed5f-4162-9da2-2c5502618492

Reproduction

The model issues a tool_use like:

{
  "name": "mcp__Desktop_Commander__lines",
  "input": {"file": "...path to a .md file...", "start": "880", "end": "1015"}
}

The Desktop Commander MCP has no lines tool. The model conflated the name with cowork_util.py lines, an unrelated Python subcommand the user invokes via start_process. This kind of confusion is the well-known LLM "hallucinated tool name" failure mode and will happen periodically with any non-trivial multi-MCP setup.

Observed behavior

  • No tool_result event written to the session audit log for that tool_use.
  • No error event surfaced to the model or the UI.
  • UI shows "thinking" state indefinitely.
  • Session sat in tool-waiting state for 63 minutes 31 seconds (measured: 21:43:26 UTC tool emit -> 22:46:57 UTC user "Stuck?" message).
  • Audit log entry 90 has the tool_use; no matching tool_result entry exists anywhere later in the file.
  • User typed "Stuck?" three times, then a Todo prompt, then explicitly asked the model to continue. None of these broke the deadlock because the SDK was waiting on a tool result that would never come.
  • Recovery required closing and restarting Claude Desktop entirely. After restart, the SDK reloaded the transcript and the session resumed normally.

Expected behavior

The MCP server (or the SDK layer above it) should immediately return a tool_use_error / tool_not_found result when the tool name does not exist in the loaded schema, allowing the model to recover and route around it. A bounded timeout on tool-use frames would also work as a defensive backstop.

Impact

Any time a model hallucinates an MCP tool name -- a known LLM failure mode, especially when adjacent legitimate names are similar -- the session is bricked until the user manually kills the host process. With long contexts and multi-MCP setups, this is not a rare edge case. The user-visible failure mode is also confusing because the UI just shows "thinking" with no indication that the SDK is stuck waiting on a tool that can never resolve.

Evidence available

  • audit.jsonl entry 90 (full JSON of the unresolved tool_use block) at the local-agent-mode-sessions session path.
  • main.log shows the gap and the subsequent Claude Desktop restart at 00:05:43 local.
  • No tool_result entry for the offending tool_use_id exists anywhere in the audit log.

Happy to share the redacted audit JSON if useful.

Suggested fix priorities

  1. SDK: validate every tool_use name against the loaded schema before forwarding to the MCP server. On mismatch, synthesize a tool_use_error result and return it to the model so it can self-correct in the same turn.
  2. SDK: enforce a configurable timeout on every tool-use frame (60s default), surfacing a recoverable error on expiry.
  3. UI: when the SDK has been waiting on a tool result for >30s, surface a visual indicator distinguishing "tool running" from "tool stuck", and offer a "cancel waiting tool call" affordance.

View original on GitHub ↗

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