[BUG] Subprocess crash surfaces as "Interrupted · What should Claude do instead?" with no actionable error
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
When the Claude Code CLI subprocess crashes due to an unhandled exception, the VSCode extension displays "Interrupted · What should Claude do instead?" — the same message shown when a user deliberately presses Escape to interrupt a running task.
This is the wrong error surface for a crash. The message implies the user did something to cause the interruption, when in reality the underlying process died. There is no indication that an error occurred, no error message, no suggestion to check logs, and no hint that anything is wrong with the installation. The actual exception is only visible by manually inspecting ~/.claude/debug/latest.
In my specific case the root cause was a CLI/extension version mismatch causing a null deref (filed separately), but the UX problem is independent of the root cause: any subprocess crash will produce this same misleading message.
What Should Happen?
When the CLI subprocess exits unexpectedly (non-zero exit code, unhandled exception, or signal), the extension should distinguish this from a user-initiated interrupt and show an appropriate error state — for example:
- "Claude Code encountered an error and stopped. Check logs for details." with a link to the debug log, or
- The actual exception message surfaced in the UI, or
- At minimum, a different message than the one shown when the user intentionally interrupts
"Interrupted · What should Claude do instead?" should be reserved for user-initiated interrupts only.
Error Messages/Logs
The actual error (only visible in ~/.claude/debug/latest, never shown in UI):
[ERROR] TypeError: TypeError: Cannot read properties of null (reading 'effortLevel')
at hH0 (file:///nix/store/.../cli.js:1845:3909)
at ew (file:///nix/store/.../cli.js:2207:4166)
at process.processTicksAndRejections (node:internal/process/task_queues:103:5)
VSCode extension output log shows the subprocess launching successfully and then:
14:32:20 [info] Received message from webview: {"type":"request",...,"title":"User Exited CLI Session"...}
The extension interprets an unhandled exception exit as "User Exited CLI Session" and displays the interrupt message.
Steps to Reproduce
Any condition that causes the CLI subprocess to exit unexpectedly will trigger this. One concrete reproduction (also filed as a separate bug):
- Install CLI at version 2.0.76, VSCode extension at 2.1.118
- Open Claude Code panel in VSCode
- Send any message
- Observe: "Interrupted · What should Claude do instead?" with no other indication of error
- Check ~/.claude/debug/latest to find the actual unhandled exception
The misleading UX is reproducible with any subprocess crash regardless of root cause.
Claude Model
Not sure / Multiple models
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.0.76 (CLI) / 2.1.118 (VSCode extension)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
The VSCode extension log shows the internal state label "User Exited CLI Session" being set on subprocess exit regardless of exit reason. This suggests the extension doesn't distinguish between clean user-initiated exits and unexpected crashes when deciding what to show the user. A clean fix would be to check the exit code/reason and branch the displayed message accordingly. The debug log path (~/.claude/debug/latest) is also not surfaced anywhere in the UI — users have no way to know it exists without external knowledge.
Note: the root cause of the crash in my case is filed as a separate bug (CLI/extension version mismatch causing null deref on effortLevel). This report is specifically about the misleading error surface, which would affect any crash scenario.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗