[BUG] ESC Key Causes Complete Terminal Freeze in Claude Code
Open 💬 20 comments Opened Jul 30, 2025 by pm0code
Summary
Pressing the ESC key during any Claude Code session causes the entire terminal to become unresponsive, requiring forced termination and resulting in complete loss of work.
Severity: CRITICAL 🔴
Environment Details (from /doctor diagnostic)
- Claude CLI Version: 1.0.63 (npm-local)
- Node.js: v22.17.1
- Path:
/home/user/.nvm/versions/node/v22.17.1/bin/node - Installation:
/home/user/.claude/local/node_modules/.bin/claude - Config Method: local
- Auto-updates: enabled
- Platform: Linux WSL2 (6.6.87.2-microsoft-standard-WSL2)
- Terminal: xterm-256color
- System: Intel Core i9-14900K, 63.8GB RAM
Steps to Reproduce
- Start Claude Code:
claude - Begin any normal workflow (editing files, running commands)
- Press ESC key at any point
- Terminal immediately becomes frozen:
- No keyboard input accepted
- No cursor movement
- No response to Ctrl+C, Ctrl+D, Ctrl+Z
- Only solution: Force close terminal window
Expected Behavior
- ESC should exit current mode gracefully OR
- ESC should be ignored if not in a specific mode OR
- Provide option to remap/disable ESC key
Actual Behavior
- Complete terminal freeze
- Loss of all unsaved work
- No recovery possible
Impact
- Data Loss: All session progress lost
- Productivity: Complete restart required
- User Trust: Critical usability issue
Diagnostic Findings
- No Debug Logging: Claude Code has no built-in logging mechanism
- No Crash Logs: No error logs generated in:
~/.claude/- System logs (journalctl)
- WSL logs
- Process State: Multiple Claude processes remain running but unresponsive
- Terminal Mode: Likely issue with terminal raw mode handling
Attempted Workarounds (All Failed)
- Setting
CLAUDE_DEBUG=1 - Setting
CLAUDE_LOG_LEVEL=debug - Looking for verbose/debug flags
- Checking for log files
Root Cause Analysis
Likely terminal mode handling issue where:
- Claude enters raw/alternative terminal mode
- ESC key triggers undefined state transition
- Terminal mode not properly restored
- Input handling loop becomes stuck
Recommendations
- Immediate: Add ESC key handling to prevent freeze
- Short-term: Implement debug logging for terminal issues
- Long-term: Add configurable key bindings
- Critical: Add graceful recovery mechanism
Additional Context
- Issue persists across multiple sessions
- Affects WSL2 environment specifically
- No workaround currently exists
- Forces users to avoid ESC key entirely
Priority: P0 - CRITICAL
This is a data loss bug that makes Claude Code unusable for users who habitually use ESC key (vim users, terminal power users).
20 Comments
same
Any solution?!
I'm experiencing this while claude is running a command with sudo, workaround: tell him to background all sudo commands.
This continues to be a problem over several Claude Code updates. It would be nice to have the esc functionality restored as there is no way to stop a Claude Code process without effectively ending your session with it. Hitting esc stops Claude Code, however since it also disables text entry you cannot continue with the session.
Environment Info
I have same problem, unable to exit terminate with Esc or any thing except terminating the Terminal Claude. very annoying
<img width="739" height="241" alt="Image" src="https://github.com/user-attachments/assets/729fc0b9-1744-4658-9346-be14d844ebbf" />
I have the same problem. Same environment: Claude Code 2.0.60 running under WSL2/Ubuntu.
I'm facing this issue on CC ver. 2.7.76
I'm having the same problem. I'm on MacOS. This has persisted a long time and makes me crazy.
I've switched some development to Antigravity.
Is this being looked at?
same
Environment:
Issue:
After pressing ESC, the Claude Code TUI often becomes effectively frozen:
This is a regression: previous versions did not exhibit this.
Same here. On windows 11. I asked claude to make overview of project, it called up 5 subagents, at first it was fast but when it was not finished in half an hour i started to investigate and it seemed that subagents viewd each file and ran each command about 5 minutes. The cpu usage was low. Using the latest windows install script.
Pressing ‘i’ after “freeze” returns the terminal into “insert” mode. “Esc” is not causing the freeze, it’s only ends the insert mode. It is not actually a freeze, but some form of “command” mode.
Is vim mode enabled?
I get the same exact experience. Everytime I press _Esc_ the terminal hangs. Here is a gif showing this. Basically every time I cancel something with _Esc_
claudeappears to be thinking!Image
In addition to that
claudehangs immediately after launching it.I can confirm this is not caused by
vimmode. I get the same experience withvimmode enabled/disabledI have never had this issue until 2.1.72. Now if I check /status or anything that takes over the UI, esc does not work. I have to kill the terminal and start over.
I found the exact same bug.
MacBook Air
13-inch, M4, 2025
Chip: Apple M4
Memory: 24 GB
Claude Diagnostics
└ Currently running: native (2.1.84)
CLI Env
└ Integrated Terminal on Cursor
└ Iterm2
└ Zsh(Terminal.app)
Root Cause Analysis — Ink Overlay Focus Restoration Failure
After reverse-engineering the v2.1.84 native binary (
strings+ code pattern analysis), here's what I found.Affected Commands
All
type: "local-jsx"overlay commands:/doctor,/status,/stats,/usageArchitecture
Claude Code uses Ink (React-based terminal UI framework). The
InternalAppclass manages:rawModeEnabledCountstdinreadable →processInput()→ key parser (keyParseState) → event emitterNORMAL_TIMEOUT=50msflush timerThe Bug
When a fullscreen overlay (e.g.
/doctor) mounts:rawModeEnabledCountonDonecallbackWhen ESC dismisses the overlay:
keyParseStatemay get stuck inincompletestate if the overlay teardown races with the 50ms escape sequence flush timerEvidence
InternalApp.handleSetRawModeusesrawModeEnabledCountref-count — incorrect decrement on overlay unmount disables raw modeskipExitHandlingprop exists in 9 components — suggests this exit-handling issue is known and selectively worked aroundprocessInputhas anincompleteEscapeTimer(50ms) — if overlay teardown occurs during an incomplete escape sequence parse, the state machine gets stuckEnv Vars Tested (None Worked)
| Env Var | Effect |
|---|---|
|
CLAUDE_ENABLE_STREAM_WATCHDOG=1| No effect on this bug ||
CLAUDE_CODE_DISABLE_VIRTUAL_SCROLL=1| No effect ||
CLAUDE_CODE_ACCESSIBILITY=1| No effect |Also tested with
/vimmode both enabled and disabled — no difference.Environment
Suggested Fix Direction
The overlay wrapper component (
r$) needs to ensure proper cleanup on unmount:rawModeEnabledCountcorrectlyreadablelistener if it was detachedincompleteEscapeTimerand resetkeyParseStateskipExitHandlingconsistently across alllocal-jsxcommands, or fix the underlying focus restoration in the Ink layerCorroborating on macOS with tmux. Same root cause as ysnotksk's Ink-overlay analysis (2026-03-26 comment).
Environment:
alternate-screen off,history-limit 50000)tmux-256colorwith truecolor supportRepro:
/mcpmenu in any Claude Code sessionkill <pid>(SIGTERM) to the claude process sometimes works, often doesn't — neededkill -9(SIGKILL) on 2 of 3 hangs todayFrequency: hit this 3x in one working session (~4 hours). Always triggered by an overlay command (
/mcpin all three cases). Same behavior on both/mcpand — separately today — another stuck overlay in agsd-executeslash-command context.Process state during hang:
claudeprocess visible inps(not crashed, just unresponsive)kill(SIGTERM) with 1s grace → sometimes dead, sometimes notkill -9always dead within ~500msRecovery workflow I landed on (in case useful for other users):
tmux list-panes -a -F "#{session_name}:#{window_index}.#{pane_index} pid=#{pane_pid} title=#{pane_title}"to find the stuck pane,pgrep -Pchain to walk the process tree under the pane pid until you hit theclaudebinary, thenkill <pid>(escalate to-9if needed). Script-ified it locally so it takes a pane title substring as arg. Happy to share if it'd help.This is a regression for me — I've been on Claude Code daily for months and only started seeing this in the 2.1.x series. Not sure exactly which version introduced it, but
/mcp,/doctor,/statusoverlays consistently trigger it now.+1 on priority. Data loss is real — unsent input / current TUI state is lost on
kill -9, and the session has to be resumed viaclaude --resume.+1 please fix this, it's a breaking issue.
Quick follow-up — sharing in case it's useful for others hitting this.
(My earlier RCA in this thread was an AI-assisted analysis of the binary, so I can't vouch for the technical details. Treat it as a guess.)
What I'm seeing on Claude Code 2.1.132 (native), macOS Tahoe / Darwin 25.2.0, Apple M4:
I don't get a hard freeze like some others report — but bare
Escdoesn't dismiss the overlays (/usage,/doctor,/status, etc.) at all, and the input becomes unusable while it stays open.Workaround that works for me: pressing
Esctogether withOption,Shift, orControldismisses the overlay and gets the input back.Cmd + Escdoesn't work (probably swallowed by macOS).i(per @0anton) doesn't help in my case either.For the rewind UI (related to #53804), I can't reproduce the freeze, but dismissal is a bit narrower and terminal-dependent:
Shift + Esc,Control + Esc,Option + Escall workOption + EscworksHope this helps anyone else stuck on the same thing while it gets sorted upstream.