[BUG] /mcp` modal freezes TUI hard on WSL2 — only reproducible without `--debug
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?
On Ubuntu 24.04 / WSL2 with Claude Code 2.1.119 (native install, Bun runtime), opening the /mcp modal hard-freezes the TUI: Enter, Esc, arrow keys, and Ctrl-C all become unresponsive. SIGINT is not processed. The only recovery is Ctrl-Z + kill -9 <pid>.
Critical clue: the bug does NOT reproduce when Claude Code is started with --debug. Same user, same config, same terminal, same session — /mcp works normally under --debug and freezes hard without it. This points to a timing-sensitive render loop where synchronous log output (only present in --debug) inadvertently breaks a bad state-update cycle.
Kernel-side inspection of a frozen process confirms it is not deadlocked on I/O and not in a CPU busy loop — the main thread repeatedly returns to epoll_wait while the process writes the TTY at ~30 Hz. Classic signature of a React/Ink render loop that re-schedules itself every frame, starving keyboard input processing.
Environment:
- Claude Code 2.1.119 (latest on npm as of this report)
- Install method:
native(~/.local/share/claude/versions/2.1.119) - Runtime: Bun (confirmed via thread names:
Bun Pool 0-7,HeapHelper,JITWorker) - Ubuntu 24.04 on WSL2, kernel
6.6.87.2-microsoft-standard-WSL2 - Windows Terminal
- Only ONE MCP server configured (
npx -y @aashari/mcp-server-atlassian-bitbucket, stdio, statusconnected) ENABLE_CLAUDEAI_MCP_SERVERS=falseis set, so no cloud connectors in the list
Not a duplicate of #27367 (2-3s lag, different mechanism), #4232 (slash command latency), #23016 (Windows 11 startup freeze), or #19988 (freeze on large MCP responses). This is specifically about the /mcp modal hard-freezing with a single server, only when --debug is off.
What Should Happen?
Opening /mcp should render the server list and immediately respond to keyboard input (Enter to select, Esc to close, Ctrl-C to abort), regardless of whether Claude Code was started with --debug. Behavior must not depend on --debug being enabled.
Error Messages/Logs
No error is printed: the TUI renders the menu successfully and then silently becomes unresponsive. Because `--debug` is off when the bug reproduces, there are no debug logs to attach — this is part of what makes the bug hard to diagnose from user logs.
Instead, here is a **kernel-side snapshot** captured on a live frozen process (PID 1376, `claude --resume`, 35s elapsed, stuck on `/mcp`):
### Threads
$ ps -T -p 1376 -o tid,stat,%cpu,wchan:20,comm
TID STAT %CPU WCHAN COMMAND
1376 Sl+ 10.8 do_epoll_wait claude <- main thread
1377 Sl+ 0.4 futex_wait_queue claude
1378 Sl+ 1.0 futex_wait_queue HeapHelper
1379 Sl+ 1.0 futex_wait_queue HeapHelper
1380 Sl+ 0.9 futex_wait_queue HeapHelper
1381 Sl+ 0.9 futex_wait_queue HeapHelper
1382 Sl+ 0.9 futex_wait_queue HeapHelper
1383 Sl+ 0.9 futex_wait_queue HeapHelper
1384 Sl+ 0.9 futex_wait_queue HeapHelper
1385 Sl+ 2.2 futex_wait_queue JITWorker
1386-1399 Sl+ ~0 futex_wait_queue Bun Pool 0-7
1397 Sl+ 0.0 do_epoll_wait HTTP Client
1445 Sl+ 0.0 wait_woken File Watcher
### Process state
$ cat /proc/1376/status | grep -E 'State|Threads|ctxt'
State: S (sleeping)
Threads: 20
voluntary_ctxt_switches: 28428 <- in ~35s of uptime = ~810/s
nonvoluntary_ctxt_switches: 36
### I/O activity (delta over 3 seconds)
rchar: +11306 bytes (~3.7 KB/s reads from TTY/sockets)
wchar: +7759 bytes (~2.6 KB/s writes to TTY)
syscr: +333 (~111 read syscalls/s)
syscw: +97 (~32 write syscalls/s) <- TTY redraw at ~30 fps
read_bytes: +0 (no disk reads)
write_bytes: +0 (no disk writes)
### Main thread wchan sampled 5 times over 1.5s
do_epoll_wait
do_epoll_wait
do_epoll_wait
do_epoll_wait
do_epoll_wait
### FDs of interest
5 × anon_inode:[timerfd] <- Bun timers
3 × anon_inode:[eventpoll]
3 × anon_inode:[eventfd]
13 × socket <- MCP stdio pipes + keep-alive HTTPS to Anthropic
6 × /dev/pts/4 <- TTY (stdin/stdout/stderr)
### Interpretation
- **Not a syscall deadlock**: main thread is in `do_epoll_wait`, not in a blocking syscall.
- **Not a CPU-bound busy loop**: `nonvoluntary_ctxt_switches` is tiny (36), CPU is ~20%.
- **App IS actively writing the TTY at ~30 fps** (`syscw` ~32/s, `wchar` ~2.6 KB/s) with zero disk I/O → the modal is continuously redrawing.
- **Input is being read** (`syscr` ~111/s) but never produces visible state transitions.
- High voluntary context switch rate (~810/s) consistent with a frame loop yielding between every tick.
This is the signature of a React/Ink render loop that keeps re-scheduling re-renders within every frame (state update inside effect/render → new render → new tick), starving the input handler. Under `--debug`, synchronous `console.log` / `process.stderr.write` calls yield the main thread at different points, which breaks whatever microtask ordering is required to trigger the loop — a textbook Heisenbug.
Steps to Reproduce
- On Ubuntu 24.04 WSL2, install Claude Code 2.1.119 (native install).
- In
~/.claude/settings.jsonset"env": { "ENABLE_CLAUDEAI_MCP_SERVERS": "false" }(optional, just to reduce the server list to one). - Configure at least one MCP server. Example (stdio, npm-based):
``bash``
claude mcp add bitbucket -s local \
-e BITBUCKET_USERNAME=... \
-e BITBUCKET_APP_PASSWORD=... \
-e BITBUCKET_WORKSPACE=... \
-- npx -y @aashari/mcp-server-atlassian-bitbucket
- Start Claude Code without
--debug:
``bash``
cd <any project dir>
claude # or: claude --resume
- At the prompt, type
/mcpand press Enter. - The modal renders showing
bitbucket · ✔ connected. - Press Enter, Esc, or Ctrl-C — nothing responds. The only exit is Ctrl-Z followed by
kill -9 <pid>.
Control (does NOT reproduce):
- Start with
claude --debuginstead. Same config, same terminal, same session —/mcpworks normally, navigation and Esc respond immediately.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.119
Platform
Anthropic API
Operating System
Ubuntu/Debian Linux
Terminal/Shell
WSL (Windows Subsystem for Linux)
Additional Information
_No response_
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗