Alt+] wedges keyboard input in legacy terminals: unterminated OSC in pinned crossterm
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
Environment
Codex CLI 0.154.0 on Linux, GNOME Terminal 3.56.2 / VTE 0.80.1, X11. Codex pins openai-oss-forks/crossterm at 45fecb9508105988f42fe6ff0441783ed3717f92.
Reproduction
- Open Codex in a terminal that sends
ESC ](1b 5d) for Alt+]. - Press Alt+], then Ctrl+C, Esc, or Ctrl+D.
- Subsequent keyboard input no longer reaches the application.
Initially observed after Alt+Up opened an asynchronous question, but also reproduced in the ordinary empty composer. CODEX_TUI_DISABLE_KEYBOARD_ENHANCEMENT=1 does not prevent it.
Expected: the key is handled or ignored and subsequent input remains available.
Actual: subsequent key bytes remain buffered inside an unterminated OSC sequence.
Evidence
A real PTY driving the exact pinned Crossterm EventStream reproduces:
1b 5d # Alt+]
03 # Ctrl+C after 100 ms: no KeyEvent
1b 04 03 # Esc, Ctrl+D, Ctrl+C: still no KeyEvents
07 03 # BEL then Ctrl+C: input recovers
A Tokio timer continues running during the stall; this is input parsing/buffering failure, not evidence that all runtime threads are deadlocked.
| Case | Pinned fork | Original crates.io Crossterm 0.29.0 |
|---|---|---|
| Ctrl+C alone | Delivered | Delivered |
| Legacy Alt+] followed by Ctrl+C | Swallowed | Both keys delivered |
CSI-u ESC [ 93 ; 3 u then Ctrl+C |
Both keys delivered | Both keys delivered |
Both fork Unix backends (mio/use-dev-tty) fail. The installed CLI was independently reproduced using isolated PTYs and a localhost Responses fixture that emits an async question. The test verifies the expanded answer UI before injecting the trigger, and checks enhancement mode requests in the default/disabled comparison. No real model calls are needed.
System VTE 0.80.1, in a minimal GTK host driven by XTest on an isolated Xvfb display, emits 1b 5d both before and after Codex's enhancement request. This is a terminal-library test, not a capture of the original session's physical keypress.
Root cause and proposed fix
The fork adds b']' => parse_osc(buffer). parse_osc returns Ok(None) until BEL/ST arrives. The reader keeps appending input without an OSC deadline. The existing lone-ESC timeout does not cover this state.
Consequently, no Alt+] KeyEvent reaches the question UI; ignoring it in async_questions/input.rs cannot fix the problem.
A dependency-layer fix should bound unfinished OSC parsing, preserve Ctrl+C even if it arrives before timeout, and retain legitimate fragmented OSC/paste behavior in both Unix backends. A tested implementation and real PTY regression are available in https://github.com/openai-oss-forks/crossterm/pull/5, targeting the dependency branch that Codex pins. Codex will also need a dependency/lockfile update after that fix becomes available upstream.
A separate incomplete-CSI issue also reproduces in original Crossterm; it is outside the OSC fix.
Patched Codex integration validation
Built Codex commit 02a8f038b87ad34d4a1dc5058eda26972ed7aa6c with dependency commit 995d98a using a test-only local Cargo path override. The installed CLI and daily configuration were not changed.
- All 12 real CLI PTY cases passed: ordinary composer and expanded asynchronous-question UI, keyboard enhancement default/disabled, and control/legacy Alt+]/CSI-u input. Ctrl+C exited normally without a BEL recovery byte. Question cases verified the expanded UI before injecting input; fixtures used localhost only.
- The normal TUI suite initially ran 4,613 tests: 4,603 passed, 9 failed, and 1 timed out. The 10 unsuccessful cases all passed in a focused 14-test rerun with
umask 077andNO_COLORunset. The original failures came from group-writable test socket directories and disabled color output; the IPC timeout waited on a server thread after its client connection was rejected. No source or snapshot changes were needed. Previously passing tests were not rerun. - The 6 default-ignored entries were separately attempted: one tmux resize smoke passed; three stopped at the GPT-5.4 model-migration prompt before reaching resize assertions. The Windows-only AltGr test is inapplicable on Linux and fails if forced. The ignored startup PTY child returned successfully but performs no standalone validation without its parent-provided environment; its real parent test passed in the normal suite. These results do not establish full manual resize coverage.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read the pinned Crossterm parser in src/event/sys/unix/parse.rs and the Unix mio reader in src/event/source/unix/mio.rs, then review the related Codex handling in async_questions/input.rs. Use the PTY regression cases described in the issue as the starting test; done means the dependency and lockfile use the available fix and legacy Alt+] no longer swallows subsequent control input.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- cli, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100