openai / openai/codex

CLI async questions remain pending after answers in normal chat; expose resolve/withdraw lifecycle

Open
#44,648 1 comment 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI tool-calls TUI
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

Problem

A structured async question can remain pending in the CLI after the user has answered it through the ordinary conversation and the assistant has understood and used that answer. The concern is lifecycle reconciliation, not how to manually skip the question.

The assistant also has no exposed operation in the affected session to mark that specific question answered or withdraw it when it becomes obsolete. Conversation state and the visible pending-question state can therefore disagree.

Environment

  • Observed September 10, 2026.
  • Installed CLI reports codex-cli 0.154.0.
  • macOS 15.7.7, build 24G720.
  • Default collaboration mode; GPT-6-Astra.
  • User screenshots show the CLI/TUI, specifically Queued follow-up inputs, ? 1 question, and its expandable question editor. This is not the desktop app's pending Steer message card.
  • The installed CLI version was checked locally; no independent process-to-executable mapping was collected for the running session.

Observed sequence

  1. During a task, the assistant called functions.request_user_input_async to ask for a documentation style preference, with two suggested options.
  2. The tool returned {"accepted":true}.
  3. The user answered via an ordinary conversation message, explaining the desired style and experience level, rather than submitting through the special question UI.
  4. The assistant received the answer, used it, and completed the requested document.
  5. Several subsequent normal conversation exchanges occurred.
  6. The CLI still displayed Queued follow-up inputs / ? 1 question.
  7. Expanding it showed the original documentation-style question and original options. The footer offered Enter to submit and Ctrl+] to skip.

The assistant's tool invocation and receipt/use of the ordinary answer are directly observable in the conversation. The stale CLI state is shown in user-provided screenshots. This is an observed incident, not a clean-room deterministic reproduction; the exact input-delivery path and queue/state transitions have not been instrumented.

Screenshots and the full conversation are not attached to avoid publishing unrelated task content. The UI labels and sequence above capture the relevant evidence.

Expected behavior

A question answered elsewhere in the same conversation should be reconciled with the original pending question. The user should not need to answer twice or manually clean up a question the assistant already considers resolved.

Please provide a reliable lifecycle for these questions, for example:

  • Stable question/request identifiers and agent-visible pending/resolved state.
  • An agent-facing operation to resolve a particular question using a received user answer, or withdraw it when it is no longer relevant.
  • UI updates that remove resolved/withdrawn questions from the pending list while preserving an appropriate transcript record.
  • Automatic reconciliation where the answer association is clear; ambiguous or unrelated follow-up input must not be treated as an answer or authorization.
  • Consistent state across later turns, reconnect, and replay, without resurrecting resolved questions.

The specific mechanism is up to maintainers. The requirement is that the assistant can track and close the question lifecycle when answers arrive outside the special UI. A manual Skip shortcut alone does not address this.

Agent-facing limitation observed

In this session, request_user_input_async accepts question titles/options and returns only {"accepted":true}. No question ID is returned by that tool result, and the available tools expose no resolve/cancel/withdraw operation for an existing question. This describes the model-facing capability in this session, not a claim that the backend has no internal IDs or lifecycle APIs.

Relevant upstream code

Current main already contains ordinary_follow_up_clears_unanswered_questions_after_accepted_input in:

https://github.com/openai/codex/blob/e25bedc166b54acadb505b587a387091097b2393/codex-rs/tui/src/chatwidget/tests/questions_tests.rs

That test appears to cover normal composer delivery clearing existing questions and suppressing the same question when added again. The observed session did not exhibit the expected cleanup. This could be a release/path discrepancy or an uncovered delivery/replay case; no root cause is established here. Clearing every question on arbitrary follow-up input also differs from explicitly resolving the question that was actually answered.

Suggested acceptance cases

  • Ask Q, receive its answer in the normal composer, incorporate it: Q is no longer pending.
  • Ask Q, later user input makes Q obsolete: the assistant can withdraw Q.
  • Ask Q1 and Q2, receive an answer only to Q1: resolve Q1 while preserving Q2.
  • Receive an unrelated status question: do not silently mark pending questions answered.
  • Reconnect/replay after resolution: Q does not reappear.
  • Resolving a question records actual user input; elapsed time or an unrelated message does not create user approval.

Related but distinct

  • #43803: desktop async question cards disappear on turn completion.
  • #43057: desktop question interface disappears after tab switching.
  • #40268: agent visibility into queued user inputs, rather than lifecycle control of agent-authored questions.

This report is about an already-answered async question remaining pending in the CLI and the missing model-facing way to reconcile or withdraw it. Filed at the affected user's request.

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

Start with codex-rs/tui/src/chatwidget/tests/questions_tests.rs, especially ordinary_follow_up_clears_unanswered_questions_after_accepted_input, and trace the request_user_input_async lifecycle and normal composer delivery. Compare the existing cleanup behavior with the listed acceptance cases, including selective resolution and reconnect/replay. Done means answered or withdrawn questions no longer remain pending or reappear, while unrelated questions are preserved.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.