Kitty keyboard protocol not restored on unclean exit, breaking Ctrl+C/Ctrl+D

Resolved 💬 2 comments Opened Mar 26, 2026 by glevco Closed Mar 26, 2026

Bug description

After exiting Claude Code, Ctrl+C and Ctrl+D sometimes stop working in the shell. Instead of sending the expected signals, the terminal prints CSI-u encoded sequences — 9;5u (tail of \e[99;5u for Ctrl+C) and 0;5u (tail of \e[100;5u for Ctrl+D).

This indicates Claude Code enabled the kitty keyboard protocol (\e[>1u) but did not send the pop sequence (\e[<u) on exit, leaving the terminal in CSI-u mode.

Reproduction

  1. Open a terminal that supports the kitty keyboard protocol (Ghostty, iTerm2, kitty, WezTerm)
  2. Run claude
  3. Exit Claude Code (the bug is intermittent — it may require an interrupted or non-clean exit)
  4. Press Ctrl+C — observe 9;5u printed instead of ^C
  5. Running printf '\e[<u' or reset restores normal behavior

The issue is more noticeable when running Claude Code inside a VM (e.g., Lima), possibly because the escape sequence has an extra PTY hop to traverse.

Expected behavior

Claude Code should always pop the kitty keyboard protocol stack on exit, regardless of how it exits (clean exit, SIGINT, SIGTERM, crash).

Workaround

Add to shell rc to defensively pop the protocol before each prompt:

# bash
PROMPT_COMMAND='printf "\e[<u" 2>/dev/null'
# zsh
precmd() { printf '\e[<u' 2>/dev/null; }

Environment

  • Claude Code v2.1.84
  • Terminal: Ghostty (but affects any kitty-protocol-capable terminal)
  • OS: macOS with Lima VM (also reproducible without VM)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗