[BUG] Regression v2.1.172: AltGr characters (@, €) swallowed in chat input on WSL2 — worked in v2.1.170
Preflight Checklist
- [x] I have searched existing issues — closest match is #56781, closed as stale on 2026-06-03 without a fix; this is a fresh regression with a bisect window
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code (2.1.173)
What's Wrong?
On German (and other European) keyboard layouts under WSL2 + Windows Terminal, AltGr-based characters can no longer be typed in the chat input since updating to v2.1.172/173. AltGr+Q (which produces @ on German layouts) inserts nothing.
This worked in v2.1.170. Bisect window: v2.1.171–v2.1.172.
The same characters work correctly in plain bash in the same WSL2 session and in all other applications.
Root Cause (analysis)
Windows synthesizes AltGr as Ctrl+Alt. The TUI now dispatches Ctrl+Alt+Q into shortcut handling before character insertion, so the @ never reaches the input. Same root-cause class as #56781.
Impact
@ is the file-mention trigger — a core interaction. Broken for German/French/Nordic/Polish/Italian layouts (see also #59045, #53451).
Workaround (verified)
~/.claude/keybindings.json, Chat context:
{"ctrl+alt+q": null, "alt+q": null, "ctrl+q": null}
Hot-reloaded, restores @ immediately. This suggests the regression is in keybinding/shortcut dispatch consuming Ctrl+Alt combos.
What Should Happen?
Ctrl+Alt+<printable key> on Windows/WSL should be treated as AltGr character input (strip the synthetic Ctrl) before shortcut dispatch.
Environment
- Claude Code 2.1.173 (native installer), regression introduced after 2.1.170
- WSL2 (Linux 6.6.x) on Windows, Windows Terminal, German keyboard layout
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Still happening in 2.1.211
Root cause found + tested workaround + suggested fix
I dug into this on an affected setup (WSL2 Ubuntu + Windows Terminal, German layout, Claude Code 2.1.211). The character loss is not in keybinding/shortcut dispatch — it's in how Claude Code negotiates the terminal keyboard protocol. Here are byte-level captures that isolate it.
Environment
WT_SESSIONset)@= AltGr+Q,€= AltGr+EWhat the terminal actually sends for AltGr+Q
Captured directly in the terminal, same profile Claude Code runs in:
cat -v, or a raw single-char read) — the character arrives clean:ESC[>1u):That decodes to
ESC[113;3u= base key 113 (q), modifier 3 (Alt) — the resolved@is not in the message at all. The terminal reports the physical key event, and AltGr surfaces as an Alt modifier.ESC[>17u):Now it's
ESC[113;3;64u— base keyq, Alt, and the resolved character@(codepoint 64) in the associated-text field.Why the character is lost
Two independent issues, both on the client side:
@, the terminal reports the base keyqplus an Alt modifier and the actual@is never transmitted. In cooked mode (capture #1) the OS resolves AltGr and hands over@directly, which is why every other app — and plain bash in the same session — works fine.113;3;64udoesn't match its pattern, so the associated-text field is never read.Downstream, the key event carries an Alt/meta modifier, and the text-input layer discards any key that has ctrl or meta set — so the keystroke is dropped silently. This is also why the existing
CLAUDE_CODE_ALTGR_AS_TEXTenv var doesn't help here: that path only triggers for Ctrl+Alt combos, but under the kitty protocol Windows Terminal reports AltGr as Alt-only, and in any case the message carries the base key (q), not@.Workaround (tested, works today)
Prevent Claude Code from enabling the kitty protocol, so AltGr characters arrive as plain bytes (capture #1 behavior):
Windows-Terminal detection keys off
WT_SESSION; with it unset, the terminal isn't in the kitty-enable allowlist, the protocol isn't turned on, and@/€type normally. Make it permanent with an alias. Caveats: this disables kitty-protocol key disambiguation generally (fine for normal editing), and it won't help inside tmux (tmux enables the protocol independently). Useenv -u(fully unset), not an empty value.Note this is only an indirect workaround because there is currently no supported way to disable the kitty keyboard protocol — a
CLAUDE_CODE_DISABLE_KITTY_KEYBOARD-style env var is itself an outstanding feature request (#27001, #27868). Shipping one would both give affected users a clean escape hatch and close those requests.Suggested fix
17instead of1). Terminals that don't support it ignore the extra bit, and the actual negotiated flags can be confirmed from the protocol's query response.@, not a droppedq. This is layout-agnostic: the terminal does the AltGr resolution and simply hands back the resolved character.ESC[113;3;64u(and the legacyESC[27;...form) through the input pipeline and asserts@is inserted — this class of bug has regressed repeatedly without one.CLAUDE_CODE_DISABLE_KITTY_KEYBOARDenv var), which is already requested in #27001 and #27868 — useful as an escape hatch for this and similar protocol-related input issues.Still happening in 2.1.234