Cowork mode: hallucinated MCP tool name causes silent SDK deadlock until manual restart
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.111and2.1.119 - Desktop Commander MCP: v0.2.39
- Encountered 2026-04-27, session id
local_04615dc0-2f23-4ac1-a07a-a4906c8dab84, CLI session5410d741-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_resultevent written to the session audit log for thattool_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 matchingtool_resultentry 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.jsonlentry 90 (full JSON of the unresolvedtool_useblock) at the local-agent-mode-sessions session path.main.logshows the gap and the subsequent Claude Desktop restart at 00:05:43 local.- No
tool_resultentry for the offendingtool_use_idexists anywhere in the audit log.
Happy to share the redacted audit JSON if useful.
Suggested fix priorities
- SDK: validate every
tool_usename against the loaded schema before forwarding to the MCP server. On mismatch, synthesize atool_use_errorresult and return it to the model so it can self-correct in the same turn. - SDK: enforce a configurable timeout on every tool-use frame (60s default), surfacing a recoverable error on expiry.
- 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.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗