openai / openai/codex

Status indicator can disappear after switching between active threads

Open
#37,942 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI session subagent TUI
Dominant language
Rust
Stars
125k
Forks
19.5k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

  • codex-cli rust-v0.148.0-alpha.1.

What subscription do you have?

  • ChatGPT Pro 20x.

Which model were you using?

  • gpt-5.6-sol.

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

  • Alacritty inside tmux.

Codex doctor report

  • Unavailable: all log recording is disabled for performance.

What issue are you seeing?

  • Switching from an active thread to a sub-agent and back can permanently hide the active thread's status indicator even though the original turn is still running.
  • The failure occurs when a thread switch overlaps the deferred status restoration window after streamed commentary finishes but before its stream queues become idle.

What steps can reproduce the bug?

  • Start a long-running turn that produces streamed commentary.
  • Wait until a commentary item finishes while its displayed stream is still draining.
  • Open a running sub-agent before the active thread's status indicator reappears.
  • Return to the main thread.
  • Repeat the switch during this short drain window if the first attempt does not reproduce the issue.
  • Observe that the main thread remains active but its status indicator can stay hidden.

What is the expected behavior?

  • A thread switch preserves both the current status visibility and any pending request to restore the indicator after streaming becomes idle.

Additional information

  • ChatWidget::finalize_completed_assistant_message sets pending_status_indicator_restore when a commentary stream has finalized but still needs restoration after its queues drain.
  • App::select_agent_thread then calls App::store_active_thread_receiver, replaces the active widget with ChatWidget::new_with_app_event, and replays the selected thread snapshot.
  • ChatWidget::capture_thread_input_state and ThreadInputState preserve running/input state but omit current_status, indicator visibility, and pending_status_indicator_restore.
  • Switching during the deferred window therefore destroys the only restore intent with the old ChatWidget; switching back reconstructs a running widget with no event left to make the status visible.
  • Preserving those status fields in the per-thread snapshot and invoking maybe_restore_status_indicator_after_stream_idle after snapshot replay addresses the issue.
  • This report was organized with Codex CLI assistance from observed behavior and source inspection.

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

Trace ChatWidget::finalize_completed_assistant_message, App::select_agent_thread, App::store_active_thread_receiver, ChatWidget::capture_thread_input_state, and ThreadInputState. Reproduce switching during the stream-drain window, then inspect snapshot replay and maybe_restore_status_indicator_after_stream_idle. Done means the active thread retains status visibility and pending restoration across switches while its turn is still running.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.