codex - 💡(How to fix) Fix Double Esc rewind can leave terminal rendering broken after exit [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openai/codex#21345Fetched 2026-05-07 03:41:31
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Author
Participants
Timeline (top)
labeled ×3unlabeled ×1

Fix Action

Fix / Workaround

A local minimal patch that appears appropriate is:

Per docs/contributing.md, external PRs are by invitation only, so I am opening this issue first with the repro, root-cause hypothesis, and patch outline instead of sending an unsolicited PR.

Code Example

// in restore_common(...)
if let Err(err) = execute!(stdout(), DisableAlternateScroll, LeaveAlternateScreen) {
    first_error.get_or_insert(err);
}

// in Tui::leave_alt_screen(), after restoring alt_saved_viewport
self.terminal.invalidate_viewport();

---

cargo fmt --manifest-path codex-rs/Cargo.toml --all
cargo test --manifest-path codex-rs/tui/Cargo.toml app_backtrack --lib
cargo check --manifest-path codex-rs/Cargo.toml -p codex-tui
RAW_BUFFERClick to expand / collapse

What version of Codex CLI is running?

codex-cli 0.128.0

What subscription do you have?

Not relevant / not captured.

Which model were you using?

Not model-specific.

What platform is your computer?

macOS / Darwin on Apple Silicon (aarch64-apple-darwin binary from Homebrew cask).

What terminal emulator and version are you using (if applicable)?

Original terminal details were not captured. The failure appears tied to the TUI alternate-screen/backtrack flow rather than model output.

What issue are you seeing?

After using the Codex CLI double-Esc rewind/backtrack flow, terminal rendering can remain broken after exiting Codex. The shell prompt appears to render over stale TUI content / with an incorrectly restored screen state, requiring a terminal reset or a new terminal session to recover cleanly.

This looks like Codex can exit while the transcript/backtrack overlay has used the alternate screen, but process-level terminal restoration does not defensively leave the alternate screen. There is also a plausible redraw-cache issue when leaving the transcript overlay: the inline viewport is restored, but the terminal diff buffer can still contain the previous alternate-screen frame, allowing the next normal-buffer draw to be computed against stale overlay state.

What steps can reproduce the bug?

  1. Start an interactive Codex CLI session.
  2. Send at least one user message so there is a rewind target.
  3. Press Esc once to prime backtrack.
  4. Press Esc again to open the transcript/backtrack overlay.
  5. Exit Codex from this flow, or close the overlay and then exit.
  6. Observe the shell/terminal after Codex exits.

What is the expected behavior?

After Codex exits, the terminal should always be restored to a normal shell-rendering state:

  • not left in the alternate screen,
  • alternate-scroll mode disabled,
  • cursor visible/default,
  • no stale Codex overlay content affecting subsequent shell rendering.

What happens instead?

The terminal can remain visually corrupted after exit, with shell output/prompt rendering over stale Codex TUI content or otherwise appearing as if the screen state was not fully restored.

Additional information

I inspected codex-rs/tui/src/tui.rs and found two likely hardening points:

  1. restore_common(...) currently restores bracketed paste, focus, raw mode, keyboard reporting, and cursor state, but does not defensively emit DisableAlternateScroll / LeaveAlternateScreen. If the app exits while an overlay or alternate-screen transition is active, the parent shell may inherit the wrong screen state.
  2. Tui::leave_alt_screen() restores the saved inline viewport but does not invalidate the terminal diff buffer. Since the alternate-screen overlay and normal inline UI use different backing screen contents, the next normal-buffer draw should be forced to repaint rather than diffing against the overlay frame.

A local minimal patch that appears appropriate is:

// in restore_common(...)
if let Err(err) = execute!(stdout(), DisableAlternateScroll, LeaveAlternateScreen) {
    first_error.get_or_insert(err);
}

// in Tui::leave_alt_screen(), after restoring alt_saved_viewport
self.terminal.invalidate_viewport();

Local validation on a checkout of openai/codex main:

cargo fmt --manifest-path codex-rs/Cargo.toml --all
cargo test --manifest-path codex-rs/tui/Cargo.toml app_backtrack --lib
cargo check --manifest-path codex-rs/Cargo.toml -p codex-tui

Results:

  • cargo test --manifest-path codex-rs/tui/Cargo.toml app_backtrack --lib: passed, 8 tests.
  • cargo check --manifest-path codex-rs/Cargo.toml -p codex-tui: passed.
  • cargo fmt completed; stable rustfmt emitted existing warnings about the repository's nightly-only imports_granularity setting.

Per docs/contributing.md, external PRs are by invitation only, so I am opening this issue first with the repro, root-cause hypothesis, and patch outline instead of sending an unsolicited PR.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Double Esc rewind can leave terminal rendering broken after exit [1 participants]