Codex CLI still renders at stale terminal size after resize
What version of Codex CLI is running?
codex-cli 0.131.0-alpha.4
What subscription do you have?
Pro plan
Which model were you using?
Not model-specific. This is TUI resize/rendering behavior.
What platform is your computer?
Darwin 25.4.0 arm64 arm
What terminal emulator and version are you using (if applicable)?
Ghostty 1.3.1. No multiplexer observed. TERM=xterm-ghostty.
What issue are you seeing?
Codex continues rendering to a stale terminal size after the enclosing terminal or pane is resized. New output remains wrapped/clipped to the old dimensions even after the terminal has been restored to a larger size.
The transcript area itself also remains trapped in a smaller box than the actual window size. Once it gets into this state, it does not seem to recover on its own.
Switching to another agent and back forces a redraw. Sometimes Ctrl-L helps. Neither is a fix.
Current repro attachment:
https://github.com/user-attachments/assets/18fd498d-f627-429d-85be-740686542f05
This is the same user-visible failure discussed in #5576. Since #5576 is being treated as fixed/closed, here is the requested fresh report:
https://github.com/openai/codex/issues/5576#issuecomment-4413826320
What steps can reproduce the bug?
- Open Codex CLI in Ghostty 1.3.1.
- Start a session that produces enough output to make wrapping and scrollback visible.
- Resize the Ghostty window or pane smaller while Codex is running.
- Resize it back larger, or toggle Ghostty focus mode so the pane changes size.
- Continue interacting with Codex.
- Observe that Codex keeps rendering as if it is still at the old size, with the transcript/content area constrained to a smaller box inside the larger terminal.
What is the expected behavior?
Codex should repaint/reflow the TUI according to the current terminal dimensions after resize. New output, transcript content, dialogs, and the input area should use the current width and height without requiring agent switching, Ctrl-L, or exit/resume.
Additional information
Observed after updating through 0.129.0, 0.130.0, and 0.131.0-alpha.4.
Related:
- #5576
- #5259
12 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Should burn more tokens filing a bug against Codex Action?
github-actions tagged this as a duplicate of #5576, but #5576 was just closed and the collaborator-suggested path was a fresh report for any case still reproducible on 0.130.0+. That's this issue.
Source state at
rust-v0.131.0-alpha.4, in case it helps triage:terminal_resize_reflowfeature isdefault_enabled: true(codex-rs/features/src/lib.rs:743-752), so 0.131.0-alpha.4 runs everyEvent::ResizethroughApp::handle_draw_pre_render(codex-rs/tui/src/app/resize_reflow.rs:354).handle_draw_size_change(codex-rs/tui/src/app/resize_reflow.rs:300), which schedules a debounced 75 ms reflow on width or height change, andmaybe_run_resize_reflow(codex-rs/tui/src/app/resize_reflow.rs:377) rebuilds viaclear_scrollback_and_visible_screen_ansi(codex-rs/tui/src/custom_terminal.rs:531).figelwump's earlier diagnostic on #5576 is the most useful evidence for narrowing this. PTY winsize updates correctly across Ghostty's focus-mode toggle (
stty -f /dev/ttysXXX sizereports the new dimensions), and a manualkill -SIGWINCH <pgrp>after the fact does not recover the stale render. So the signal isn't being missed and a retroactive resize event isn't enough to repair the screen for this terminal/transition combination. The gap is somewhere downstream ofEvent::Resizearrival in the resize-reflow rebuild path, not in signal delivery.bmizerany's "switching agents fixes it" workaround on #5576 fits that picture: a side-effect that forces
Terminal::invalidate_viewport(codex-rs/tui/src/custom_terminal.rs:492) recovers, while the resize-driven path apparently doesn't.Can you confirm whether Terminal resize reflow is enabled in
/experimental, or whether your config.toml has[features] terminal_resize_reflow = falsein any active profile?It was on. I have now tried with both on and off in 131-alpha4 and the issue persists for both configurations.
Thanks for the toggle datapoint, that changes the analysis.
The
terminal_resize_reflowfeature gates two distinct paths:App::handle_draw_pre_renderruns the reflow pipeline at all (codex-rs/tui/src/app.rs:1115-1117). With the feature off, the only pre-render resize work isrefresh_status_line(). No scheduling, no transcript rebuild, noclear_scrollback_and_visible_screen_ansicall.app.rs:1156-1174).Tui::draw_with_resize_reflowcallsupdate_inline_viewport_for_resize_reflow(tui.rs:739).Tui::drawcallsupdate_inline_viewport(tui.rs:682) plus the cursor-position-awarepending_viewport_areaheuristic (tui.rs:923-943).My earlier trace through
clear_scrollback_and_visible_screen_ansiis on the reflow rebuild path and doesn't run with the feature off, so your test rules that out. With the toggle off, the only resize-time terminal manipulation isscroll_region_upinsideupdate_inline_viewport(tui.rs:693-704) plus whatever offsetpending_viewport_areaproduces from a cursor-position query during the resize. Either path can leave the viewport positioned such that the next implicitinvalidate_viewportdoesn't repaint the missing rows."Switching agents recovers" still fits as a workaround because it eventually forces
Terminal::invalidate_viewport(custom_terminal.rs:492) downstream of whatever state the resize handler left.Thanks, that helps narrow it down. A few follow-up details would help distinguish whether this is specific to Ghostty's resize sequence or something lower-level in Codex's viewport handling:
!stty sizeand paste the output from both points?``
sh
``printf 'TERM=%s\nTERM_PROGRAM=%s\nTERM_PROGRAM_VERSION=%s\nCOLORTERM=%s\nTMUX=%s\nSTY=%s\nZELLIJ=%s\n' \
"$TERM" "$TERM_PROGRAM" "$TERM_PROGRAM_VERSION" "$COLORTERM" "$TMUX" "$STY" "$ZELLIJ"
term, shell integration, splits/focus mode, scrollback, or resize behavior, please include that too.Since you already confirmed
Terminal resize reflowbehaves the same both on and off, the most useful next signal is whether Ghostty reports the new terminal size correctly while Codex remains visually stuck at the old one.Yes to the former.
It reports "not a terminal." But there is a clue: When I size wider, then focus with the mouse, type something, the input appears about as many cols up as it grew wider... maybe? See:
<img width="2452" height="936" alt="Image" src="https://github.com/user-attachments/assets/b7f8bd18-9a4c-470e-aaa5-d8d16799de61" />
<img width="1788" height="448" alt="Image" src="https://github.com/user-attachments/assets/d51f56d3-45c3-4a1d-b4d4-bb0b06841166" />
I do not.
See previous reports with recordings. I see what they see.
bmizerany's image shows the input row appearing roughly N columns up after the terminal grew N columns wider. That signature is specific: it matches
Tui::pending_viewport_area(codex-rs/tui/src/tui.rs:923-943) on the legacy draw path (reflow=off).The heuristic queries
terminal.get_cursor_position()after a size change, computescursor_pos.y - last_known_cursor_pos.y(lines 935-938), and applies the delta as a viewport offset. The inline comment on line 932 admits it's "a heuristic that seems to work well at least in iTerm2." iTerm2 doesn't reflow scrollback by default; Ghostty does, on width change.When the terminal widens, Ghostty unwraps lines in scrollback above the inline area. The cursor moves up by the count of newly-unwrapped lines (roughly proportional to the width delta, depending on how many lines actually wrapped at the old width).
pending_viewport_areainterprets this cursor delta as "the terminal moved me" and offsets the viewport upward by that many rows. The next render lands above the actual cursor row, producing the "input N cols up as it grew wider" picture.One discriminator that's cheap for the legacy path: when width changes but height does not, and the inline area is bottom-aligned (which it always is for the input prompt), the correct delta is zero. The terminal did not reposition the inline area; the scrollback above it shortened.
That covers reflow=off. Reflow=on uses
Tui::draw_with_resize_reflow, which intentionally skipspending_viewport_area(per the doc comment at line 869-870). The symptom on that path comes from a different fault site, most likely somewhere in the transcript rebuild pipeline (clear_scrollback_and_visible_screen_ansithenmaybe_run_resize_reflow). The visual signature is similar, the path is distinct.Mouse-focus or keystroke recovery fits both paths: an
invalidate_viewporttriggered later re-queries the cursor at a stable moment after the reflow has settled.I have the same issue. Latest version of Codex. More than "I have the same issue" I should just say "the issue never went away" since this has been happening since I first started using Codex many months ago and has never been fixed.
@masinov can you run
codex doctor --alland send me the response so we can investigate it further?Codex Doctor v0.131.0 · linux-x86_64
Environment
✓ runtime npm
version 0.131.0
install method npm
commit unknown
executable /usr/lib/node_modules/@o…-linux-musl/codex/codex
✓ install consistent
context npm
managed by npm: yes · bun: no · package root /usr/lib/node_modules/@openai/codex
PATH entries (2) /usr/bin/codex
/bin/codex
npm update target /usr/lib/node_modules/@openai/codex
✓ search ripgrep 15.1.0 (rev af60c2de9d) (system, rg)
search command rg
search provider system
search command readiness ripgrep 15.1.0 (rev af60c2de9d)
✓ terminal VS Code 1.112.0
terminal VS Code
TERM_PROGRAM vscode
terminal version 1.112.0
stdin is terminal true
stdout is terminal true
stderr is terminal true
terminal size 196x48
color output enabled
COLORTERM truecolor
effective locale en_US.UTF-8
SSH_CONNECTION present
SSH_CLIENT present
VSCODE_IPC_HOOK_CLI present
✓ state databases healthy
CODEX_HOME ~/.codex (dir)
log dir ~/.codex/log (dir)
sqlite home ~/.codex (dir)
state DB ~/.codex/state_5.sqlite (file) · integrity ok
log DB ~/.codex/logs_2.sqlite (file) · integrity ok
active rollouts 147 files · 371.63 MB (avg 2.53 MB)
archived rollouts 0 files · 0 B (avg 0 B)
Configuration
✓ config loaded
model gpt-5.4 · openai
cwd ~/projects/******
config.toml ~/.codex/config.toml
config.toml parse ok
MCP servers 0
feature flags 28 enabled · 0 overridden
enabled flags shell_tool, unified_exec, shell_snapshot, terminal_resize_reflow, sqlite, hooks, enable_request_compression, multi_agent, apps, tool_search, tool_suggest, plugins, plugin_hooks, in_app_browser, browser_use, browser_use_external, computer_use, plugin_sharing, image_generation, skill_mcp_dependency_install, steer, guardian_approval, collaboration_modes, tool_call_mcp_elicitation, personality, fast_mode, tui_app_server, workspace_dependencies
✓ auth auth is configured
auth storage mode File
auth file ~/.codex/auth.json
stored auth mode chatgpt
stored API key false
stored ChatGPT tokens true
stored agent identity false
✓ mcp no MCP servers configured
✓ sandbox restricted fs + restricted network · approval OnRequest
approval policy OnRequest
filesystem sandbox restricted
network sandbox restricted
linux helper ~/.codex/tmp/arg0/codex-…fbp/codex-linux-sandbox
execve wrapper helper ~/.codex/tmp/arg0/codex-…bp/codex-execve-wrapper
Updates
✓ updates update configuration is locally consistent
startup update check true
update action npm install -g @openai/codex
version cache ~/.codex/version.json
cached latest version 0.130.0
last checked at 2026-05-18 13:05 UTC
dismissed version 0.116.0
npm update target /usr/lib/node_modules/@openai/codex
latest version 0.131.0
latest version status current version is not older
Connectivity
✓ network no proxy env vars
proxy env vars none
✓ websocket connected (HTTP 101 Switching Protocols) · 15s timeout
model provider openai
provider name OpenAI
wire API responses
supports websockets true
proxy env vars none
connect timeout 15000 ms
auth mode chatgpt
endpoint wss://chatgpt.com/backend-api/<redacted>
DNS 2 IPv4, 2 IPv6, first IPv4
handshake result HTTP 101 Switching Protocols
reasoning header false
models etag present true
server model present false
✓ reachability active provider endpoints are reachable over HTTP
reachability mode ChatGPT auth
ChatGPT base URL https://chatgpt.com/backend-api/ reachable (HTTP 404)
Background Server
○ app-server not running (ephemeral mode)
daemon state dir ~/.codex/app-server-daemon
settings ~/.codex/app-server-daemon/settings.json (missing)
pid file ~/.codex/app-server-daemon/app-server.pid (missing)
update-loop pid file ~/.codex/app-server-daem…/app-server-updater.pid (missing)
control socket ~/.codex/app-server-cont…app-server-control.sock
status not running
mode ephemeral
─────────────────────────────────────────────────────────────
13 ok · 1 idle · 0 warn · 0 fail ok