openai / openai/codex

Alt+] wedges keyboard input in legacy terminals: unterminated OSC in pinned crossterm

Open
#44,786 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI TUI
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

  1. Open Codex in a terminal that sends ESC ] (1b 5d) for Alt+].
  2. Press Alt+], then Ctrl+C, Esc, or Ctrl+D.
  3. 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 077 and NO_COLOR unset. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.