Skip to content

TUI can get stuck with 'Messages to be submitted after next tool call' when sending during active output #15842

Open

Description

@JiaJunDeng5930

What version of Codex CLI is running?

codex-cli 0.116.0

What subscription do you have?

ChatGPT Pro

Which model were you using?

GPT-5.4

What platform is your computer?

Linux 6.6.87.2-microsoft-standard-WSL2 x86_64 x86_64

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

tmux 3.4

What issue are you seeing?

When the model is still outputting and I press Enter to send a new message immediately (not queueing a later draft manually, but trying to submit right away), the TUI can get stuck showing:

Messages to be submitted after next tool call (press esc to interrupt and send immediately)

In the broken case:

  • the current output stops
  • no further tool call happens
  • the pending message is never sent automatically
  • the footer/status remains in the pending-steer state indefinitely

So from the user's perspective, the message is accepted into the UI, but it never actually becomes the next turn.

This looks different from normal queued follow-up behavior. The problem is specifically the "send immediately while output is still in progress" path getting stuck after the active output finishes.

What steps can reproduce the bug?

  1. Start a normal turn in the TUI so the model is actively streaming output.
  2. While output is still in progress, type a follow-up message.
  3. Press Enter before the current turn has fully finalized.
  4. Observe that the TUI shows:
    Messages to be submitted after next tool call (press esc to interrupt and send immediately)
  5. Wait for the current output to stop naturally.

Observed result:

  • the message stays in the pending-steer preview
  • it is not submitted automatically after output stops
  • the TUI appears stuck in this state until manually interrupted or otherwise recovered

What is the expected behavior?

One of these should happen reliably:

  • if the current turn is still steerable, the pending message should be consumed and become the next model request automatically
  • if the current turn is already ending and can no longer accept steer input safely, the message should be converted into a normal queued follow-up and sent as the next turn after completion
  • in either case, the TUI should not remain indefinitely stuck on Messages to be submitted after next tool call

Additional information

This appears to be a turn-finalization race between TUI pending-steer state and core pending-input handling.

From local code inspection, the rough failure mode seems to be:

  • TUI classifies the submission as a pending steer because agent_turn_running is still true
  • core accepts the input into active-turn pending_input
  • if the input lands in the narrow window after the final run_turn() iteration has effectively ended but before teardown is fully complete, it can miss the path that would start the next follow-up request
  • TUI then continues waiting for the pending steer to be cleared by the usual completion path, but that follow-up never starts, so the preview remains stuck

Relevant code paths I found while investigating:

  • codex-rs/tui/src/chatwidget.rs
  • codex-rs/core/src/codex.rs
  • codex-rs/core/src/tasks/regular.rs
  • codex-rs/core/src/tasks/mod.rs

Potentially related issues:

There is also an existing ignored/flaky core test that seems closely related to this class of behavior:

  • core/tests/suite/pending_input.rs -> injected_user_input_triggers_follow_up_request_with_deltas

Activity

  1. added
    bugSomething isn't working
    CLIIssues related to the Codex CLI
    TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal display
    on Mar 26, 2026
  2. github-actions commented on Mar 26, 2026

    @github-actions
    Contributor

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

    Powered by Codex Action

  3. etraut-openai commented on Mar 26, 2026

    @etraut-openai
    Contributor

    We are in the process of rewriting the TUI on top of the "app server" layer, which is used for other clients like the Codex app. The existing TUI implementation will be retired within the next week or so. It's likely that the bug you're experiencing does not existing in the new TUI implementation. You can enable it by using the /experimental flag and enabling the "App Server TUI" feature, then restarting the CLI.

  4. jkaunert commented on Apr 11, 2026

    @jkaunert

    I think there is a broader core-runtime bug family behind this, not just a TUI-only pending-preview problem.

    I took a private fork and re-extracted a narrow runtime slice against rust-v0.120.0 that fixes turn progression when follow-up state arrives while the current stream is still winding down.

    The important part is not the Apple/plugin context from my fork. The important part is the generic runtime behavior:

    • follow-up input or completed tool output can arrive while the active turn is still formally open
    • the active stream then reaches a stale completion path instead of progressing immediately from the newly available follow-up state
    • from the user side, the accepted follow-up exists, but the next meaningful turn does not start when it should

    That seems strongly aligned with the mechanism described in this issue:

    • accepted pending follow-up state
    • narrow finalization window
    • no reliable preemption or handoff into the next request

    I also found a related symptom in #16339, where rejection follow-up text can arrive late enough that the model continues without the user’s intended steer.

    For reference, my local validation slice is:

    • branch: upstream/tool-output-preemption-v120
    • commit: 32d01a4bd
    • test: cargo test -p codex-core pending_input -- --nocapture

    If useful, I can add a design-only follow-up here describing the exact receive-loop behavior change without posting code.

  5. JiaJunDeng5930 commented on Apr 12, 2026

    @JiaJunDeng5930
    Author

    Thanks. I checked the current main branch against the mechanism you described, and this does look closer to a broader core turn-progression / pending-follow-up timing family than to a purely TUI-local preview bug.

    What I could confirm from the repo:

    • The TUI string in this issue is only the pending-steer preview surface. The actual follow-up handoff is owned by core pending-input / turn-finish scheduling.
    • Main has since landed fixes in this area that line up with the same general mechanism:
    • Those changes add core regression coverage specifically around follow-up state arriving while the current turn is still winding down, including reasoning/commentary boundaries and post-compaction continuation ordering.

    So I think your read is directionally correct: this issue fits the same runtime handoff family, not just a stale TUI footer state.

    One caveat from current main: the most direct regression test for the original “send another user message while output is still streaming” path in core/tests/suite/pending_input.rs is still marked ignored/flaky. Therefore, while the broader runtime area has clearly been addressed, the exact original path from this issue does not yet appear to have a stable always-on regression test on main.

    That makes me think this issue is at least partially explained by fixes that already landed, but the original user-input-during-active-output race is still worth treating as a distinct validation target unless someone can confirm it is now covered reliably by newer tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    TUIIssues related to the terminal user interface: text input, menus and dialogs, and terminal displaybugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions