Ctrl+C / Escape doesn't interrupt during Boondoggling state
Summary
Ctrl+C and Escape fail to interrupt Claude Code while it's in the "Boondoggling" (thinking/streaming) state. The UI shows ctrl+c to interrupt but keypresses are ignored.
Environment
- Claude Code: npm global install via nvm (Node v22.21.1)
- Platform: WSL2 (Ubuntu) on Windows 11
- Terminal: Standard pts
Expected Behavior
Pressing Ctrl+C or Escape during API streaming should interrupt the request.
Actual Behavior
Keypresses are ignored. The only way to interrupt is kill -INT <pid> from another terminal.
Root Cause Analysis
Terminal is in raw mode (-isig), which is correct for a TUI app:
stty -a -F /dev/pts/4
...
-isig -icanon -iexten -echo
This means Ctrl+C doesn't generate SIGINT — it sends raw bytes (0x03) that Claude Code must handle via its own keypress handler.
The keybinding IS registered:
// From cli.js
{context: "Global", bindings: {"ctrl+c": "app:interrupt", ...}}
But during "Boondoggling", the event loop isn't polling stdin for keypresses. All threads are sleeping:
Thread 58597: state=S wchan=do_epoll_wait
Thread 58598: state=S wchan=do_epoll_wait
Thread 58599-58607: state=S wchan=futex_wait_queue
The main thread's epoll doesn't appear to include stdin in its wait set during API streaming.
Workaround
From another terminal:
kill -INT <pid>
This bypasses the raw terminal and delivers SIGINT directly. The process has a handler registered (SigCgt bit 2 is set) so it interrupts gracefully.
Suggested Fix
Ensure stdin is included in the epoll set during API streaming, or use a separate thread/signal handler for interrupt detection that doesn't depend on the main event loop.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗