[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

  1. Start Claude Code: claude
  2. Begin any normal workflow (editing files, running commands)
  3. Press ESC key at any point
  4. 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

  1. No Debug Logging: Claude Code has no built-in logging mechanism
  2. No Crash Logs: No error logs generated in:
  • ~/.claude/
  • System logs (journalctl)
  • WSL logs
  1. Process State: Multiple Claude processes remain running but unresponsive
  2. 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:

  1. Claude enters raw/alternative terminal mode
  2. ESC key triggers undefined state transition
  3. Terminal mode not properly restored
  4. Input handling loop becomes stuck

Recommendations

  1. Immediate: Add ESC key handling to prevent freeze
  2. Short-term: Implement debug logging for terminal issues
  3. Long-term: Add configurable key bindings
  4. 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).

View original on GitHub ↗

20 Comments

quantranorangelogic · 11 months ago

same

ESJavadex · 10 months ago

Any solution?!

uliano · 9 months ago

I'm experiencing this while claude is running a command with sudo, workaround: tell him to background all sudo commands.

drewf · 8 months ago

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

  • Platform: win32
  • Terminal: windows-terminal
  • Version: 2.0.28
  • Feedback ID: 632e7b08-3e21-4d2c-a91d-fed7619aefe0
jastranlove2020 · 8 months ago

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" />

0anton · 7 months ago

I have the same problem. Same environment: Claude Code 2.0.60 running under WSL2/Ubuntu.

gentksb · 6 months ago

I'm facing this issue on CC ver. 2.7.76

andrewault · 6 months ago

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?

Awakehsh · 6 months ago

same

Environment:

  • macOS Tahoe 26.2
  • Claude Code v2.1.4
  • Repro on both iTerm2 and macOS Terminal (not terminal-specific)

Issue:
After pressing ESC, the Claude Code TUI often becomes effectively frozen:

  • cannot edit input / cannot send messages
  • Ctrl+C also does nothing (no interrupt)

This is a regression: previous versions did not exhibit this.

taunoCL · 5 months ago

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.

0anton · 5 months ago

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.

thirking · 5 months ago

Is vim mode enabled?

specialkapa · 4 months ago

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_ claude appears to be thinking

!Image

In addition to that claude hangs immediately after launching it.

specialkapa · 4 months ago
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.

I can confirm this is not caused by vim mode. I get the same experience with vim mode enabled/disabled

eristoddle · 4 months ago

I 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.

ysnotksk · 3 months ago

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)

ysnotksk · 3 months ago

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, /usage

Architecture

Claude Code uses Ink (React-based terminal UI framework). The InternalApp class manages:

  • Raw mode via ref-counted rawModeEnabledCount
  • Keyboard input: stdin readable → processInput() → key parser (keyParseState) → event emitter
  • Escape sequence parsing with NORMAL_TIMEOUT=50ms flush timer

The Bug

When a fullscreen overlay (e.g. /doctor) mounts:

  1. It registers keyboard listeners and/or increments rawModeEnabledCount
  2. ESC key triggers overlay dismiss via onDone callback

When ESC dismisses the overlay:

  1. The overlay unmounts
  2. Focus restoration fails — the main input component doesn't properly regain keyboard event listeners
  3. keyParseState may get stuck in incomplete state if the overlay teardown races with the 50ms escape sequence flush timer
  4. Result: stdin stays in raw mode but no component processes key events → terminal appears frozen

Evidence

  • InternalApp.handleSetRawMode uses rawModeEnabledCount ref-count — incorrect decrement on overlay unmount disables raw mode
  • skipExitHandling prop exists in 9 components — suggests this exit-handling issue is known and selectively worked around
  • processInput has an incompleteEscapeTimer (50ms) — if overlay teardown occurs during an incomplete escape sequence parse, the state machine gets stuck
  • Issue #32728 ("/status cannot be dismissed") is the same root cause

Env 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 /vim mode both enabled and disabled — no difference.

Environment

  • Claude Code: 2.1.84 (native)
  • macOS Tahoe (Darwin 25.2.0)
  • Apple M4, 24GB RAM
  • Terminals: iTerm2, Terminal.app

Suggested Fix Direction

The overlay wrapper component (r$) needs to ensure proper cleanup on unmount:

  1. Restore rawModeEnabledCount correctly
  2. Re-attach the main input's readable listener if it was detached
  3. Clear any pending incompleteEscapeTimer and reset keyParseState
  4. Apply skipExitHandling consistently across all local-jsx commands, or fix the underlying focus restoration in the Ink layer
w3geekery · 2 months ago

Corroborating on macOS with tmux. Same root cause as ysnotksk's Ink-overlay analysis (2026-03-26 comment).

Environment:

  • macOS (Darwin 25.3.0)
  • Claude Code 2.1.119 (native)
  • iTerm2 + tmux 3.6a (alternate-screen off, history-limit 50000)
  • Terminal: tmux-256color with truecolor support
  • Shell: zsh

Repro:

  1. Open /mcp menu in any Claude Code session
  2. ESC to dismiss — menu doesn't close
  3. Input completely unresponsive (no typing, no Ctrl+C, no Ctrl+D)
  4. kill <pid> (SIGTERM) to the claude process sometimes works, often doesn't — needed kill -9 (SIGKILL) on 2 of 3 hangs today

Frequency: hit this 3x in one working session (~4 hours). Always triggered by an overlay command (/mcp in all three cases). Same behavior on both /mcp and — separately today — another stuck overlay in a gsd-execute slash-command context.

Process state during hang:

  • claude process visible in ps (not crashed, just unresponsive)
  • Pane PID + child PIDs all alive; specstory wrapper OK
  • kill (SIGTERM) with 1s grace → sometimes dead, sometimes not
  • kill -9 always dead within ~500ms

Recovery 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 -P chain to walk the process tree under the pane pid until you hit the claude binary, then kill <pid> (escalate to -9 if 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, /status overlays 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 via claude --resume.

TedYav · 2 months ago

+1 please fix this, it's a breaking issue.

ysnotksk · 2 months ago

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 Esc doesn'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 Esc together with Option, Shift, or Control dismisses the overlay and gets the input back. Cmd + Esc doesn'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:

  • macOS Terminal.app: Shift + Esc, Control + Esc, Option + Esc all work
  • iTerm2: only Option + Esc works

Hope this helps anyone else stuck on the same thing while it gets sorted upstream.