macOS/Kitty: TUI can remain non-reactive after task_complete while process stays busy

Open 💬 2 comments Opened Apr 24, 2026 by Don-Yin
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

0.124.0

What platform is your computer?

macOS 26.4.1 arm64

What terminal emulator and version are you using?

Kitty 0.46.1

What issue are you seeing?

I observed multiple Codex CLI TUI sessions where the terminal UI became non-reactive while the session transcript had already recorded completion.

The important state mismatch:

  • the live Kitty tab still contained a running Codex process
  • Kitty reported the window as not at a shell prompt, so the tab looked busy
  • the corresponding Codex JSONL rollout's last event was event_msg / task_complete
  • the UI did not accept useful interaction in the original tab
  • this happened in more than one live Kitty tab on the same machine

This made the session look stuck even though the recorded task had completed. I had to preserve the JSONL transcript and visible Kitty screen, then launch a fresh codex fork/codex resume tab.

Local diagnosis method

I correlated the live Kitty window with the Codex session JSONL using kitty @ ls, lsof -p <codex-pid>, and the latest event in the rollout file.

The stale condition was:

source: live Kitty window with Codex process
kitty state: busy / not shell prompt
jsonl last event: event_msg.task_complete
diagnosis: stale-ui

A fresh revive-launched tab can be created with:

codex fork --no-alt-screen <session-id>
# or
codex resume --no-alt-screen <session-id>

Expected behavior

After task_complete, the TUI should return to a reactive input state, or at least expose a recoverable error state. The original tab should not remain in a busy/non-reactive state after completion is recorded.

Actual behavior

The original Kitty tab stayed alive but non-reactive. The transcript was complete on disk, but the TUI did not recover.

Related issues

This appears related to stale TUI/busy-state reports such as:

  • #16904
  • #12645
  • #14314

but this report is specifically macOS + Kitty + Codex CLI 0.124.0, with the observed mismatch between live Kitty state and JSONL task_complete.

Workaround

I built a local recovery script that:

  1. discovers live Kitty/Codex tabs
  2. maps each live process back to its .codex/sessions/**/*.jsonl
  3. flags live windows whose rollout ends in task_complete as stale
  4. preserves raw JSONL, markdown export, and visible Kitty screen text
  5. launches codex fork or codex resume in a new Kitty tab
  6. only closes the old stale Kitty tab after the replacement tab is confirmed alive

I can provide more diagnostics if there is a preferred debug command or log source for TUI state.

View original on GitHub ↗

2 Comments

github-actions[bot] contributor · 4 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #18860

Powered by Codex Action

jleechan2015 · 1 month ago

Reproduced a closely matching macOS case on Codex CLI 0.144.1, with one additional lifecycle detail: an active /goal caused a second continuation after the first persisted task_complete, the live TUI remained in a Working/Goal state, and the Codex process later exited without a crash report before resume --last restored the thread.

Environment

  • Codex CLI: 0.144.1
  • Model: gpt-5.6-sol, high reasoning
  • Auth: ChatGPT
  • Platform: Darwin 24.5.0 arm64 arm
  • Terminal/multiplexer: cmux 0.64.16 (96)
  • Thread: 019f5408-e891-73b0-808e-b8fb326dc490

Sanitized timeline (2026-07-12 PDT)

  • 14:00:05: final assistant answer persisted.
  • 14:00:06: rollout persisted event_msg/task_complete.
  • 14:00:25: active goal generated a new codex_internal_context goal continuation.
  • 14:00:44: second final assistant answer reported the goal completed.
  • 14:00:45: rollout persisted another task_complete.
  • The live surface still appeared active (Working / Goal achieved) instead of returning cleanly.
  • 14:06:52: macOS unified log recorded the older Codex PID terminating via proc_exit; no signal/reason was exposed.
  • 14:06:58: codex resume --last was launched and recovered the same thread.

Forensics

  • Rollout contains normal tool completions and both task_complete records; no turn abort or panic around completion.
  • No Codex Crashpad minidump and no macOS Codex crash report.
  • No reboot or OOM event occurred.
  • Current resumed process is attached to the same worktree/PTY and the transcript is intact.
  • Resource pressure may contribute: state_5.sqlite was about 2.65 GB and this thread had accumulated a very large history with many subagents, but system memory was not exhausted.

This looks like a TUI/goal/session lifecycle state mismatch rather than a native crash: durable core state reaches completion, while the live UI remains busy/non-reactive and may later lose/exit the surface.

Expected behavior: after the active goal is marked complete, the TUI should reliably consume the final completion notification, clear the Working state, and remain usable. If the process/session exits, it should show an explicit recoverable diagnostic rather than silently requiring resume --last.