Codex CLI marks turn complete while follow-up is still needed after progress message
Summary
Codex CLI can prematurely mark a turn as complete after the assistant emits a commentary/progress message that promises a next action. The main thread stops before the next tool call or final answer is produced. This is very visible when the user asks for a subagent workflow, but the evidence shows the subagent is never actually spawned.
Environment
- Codex CLI: 0.139.0
- Source: codex-tui / CLI
- Model: gpt-5.5
- Reasoning effort: xhigh
- Config: features.multi_agent=true, agents.max_threads=6, agents.max_depth=2
- Thread id: 019eb0a0-47c5-7703-8926-a7492ea62f2f
Reproduction
- Start Codex CLI in an existing trusted project.
- Ask:
使用子agent查询一下明天北京的天气 - The assistant emits a progress message saying it will continue and attempt to call/check subagent tooling.
- The turn is immediately marked complete and no further tool call/final answer happens.
- Send a follow-up such as
为什么停止了?; the same pattern can repeat: progress message is emitted, then the turn completes before doing the promised action.
Expected behavior
If the assistant says it will continue with a tool call or follow-up action, Codex should continue the turn until that action completes or a final/blocking response is produced.
Actual behavior
Codex records task_complete immediately after the progress/commentary message. No subagent or deferred multi-agent tool call is created.
Local evidence
- Session transcript shows
task_completeimmediately after the assistant message at around 2026-06-10 16:24 local time. state_5.sqlitehas nothread_spawn_edgesfor the current thread and noagent_jobs/agent_job_items, so this is not a child-agent hang.- Internal log examples show
model_needs_follow_up=trueandneeds_follow_up=truefor affected turns, but the user-visible run still ended. - No relevant
ERRORwas found in the thread logs. WARNs seen were unrelated plugin manifest/skill loader warnings and analytics 401 telemetry noise.
Impact
This makes subagent workflows appear broken and also affects ordinary multi-step turns where the assistant first emits a progress update and then should continue working.
I can provide the session transcript privately if needed, after reviewing it for sensitive local context.
7 Comments
A triage angle that may help: this sounds like the turn-finalization path is trusting the model-visible progress message too much, even though the internal state still says a follow-up is required.
The most useful regression test might be an agent-loop/session test where the model emits a commentary/progress item, the harness marks
needs_follow_up=true, and no tool call has been emitted yet. The assertion would be that the session must not publishtask_completeuntil either the follow-up request is actually executed or a final/blocking response is produced.That would also separate this from the subagent layer: the issue is reproducible before any
thread_spawn_edges/agent_jobsentry exists, so the likely boundary is “assistant message with follow-up intent” -> “turn completion”, not child-agent execution.Reproduced on 0.144.1, with rollout-level evidence for a stronger variant: the turn completes right after the progress message **even when the promised subagent was actually spawned** — the dispatched child is then aborted without delivering, and the parent sits idle until the user manually pokes it.
Environment
@agentclientprotocol/codex-acp1.1.2; client is a native macOS ACP app)spawn_agent/wait_agentin use)019f4df4-33d0-7c62-b2e3-e718f9d49167Key sequence (from the parent rollout, timestamps UTC)
The child thread confirms the work was dispatched and then abandoned (child rollout
019f4e92-fbd5-78f2-ad23-ee37932ef5eb,source.subagent.thread_spawn.parent_thread_id= the parent above):So this isn't only the "subagent never spawned" case from the original report: the finalization path marks the turn complete two seconds after
spawn_agent, with nowait_agentever issued for the new child, and the message text ("Continuing. … is underway next.") states unambiguous follow-up intent. From the user's side the agent just goes silent mid-plan.It recurs within a single session
Same thread, same pattern, four more times — each
task_completelands seconds after a progress message that promises a next action, and work only resumes on manual user input ("and?", "go on", …):Possibly-related context
The same session also shows the
wait_agenttimeout behavior from #24951 / #26822: bursts of 40+ consecutivewait_agent {"timeout_ms":30000}→{"message":"Wait timed out.","timed_out":true}over ~45 minutes while children ran. I mention it because the turn-completion bug and the children-never-reporting bug compound each other: the model burns many wait cycles, falls back to narrating progress, and that narration is exactly what the finalizer then accepts as a turn boundary.Happy to share the full parent/child rollouts privately if useful.
Additional GPT-5.6 reproduction: visible blocking-style final response despite a fully defined next action
This issue is also reproducing in a long-running single-agent implementation workflow on GPT-5.6 Terra / a newer Codex build. The previous combination (GPT-5.5 + an earlier Codex build) did not exhibit this behavior in the same project workflow.
Latest occurrence
The agent had already implemented and tested the targeted lifecycle layer. It then returned this as the final user-visible message:
The turn ended after roughly 24 seconds.
Why this appears erroneous
The message converted ordinary implementation complexity into a session-level blocker, even though the remaining work was exactly the approved task scope.
Repeated pattern in the same workflow
Earlier examples from the same session included:
and:
In both cases, the turn completed immediately after the progress/future-intent message and before the promised implementation continued.
Expected behavior
When the model has a defined next action, available tools, and no genuine blocker, it should continue with tool calls or implementation. Complexity or risk should trigger incremental TDD and validation—not a premature terminal response.
Actual behavior
Codex emits a progress or self-imposed blocking message, returns control to the user, and requires a manual follow-up such as
continueto resume the same approved task.This looks like the same turn-finalization problem described in this issue, now reproduced with GPT-5.6 and without any subagent dependency.
Additional reproduction: GPT-5.6 Terra repeatedly finalizes visible non-empty progress turns in VS Code and desktop app
I can reproduce the same core turn-finalization problem in a long-running, single-agent implementation workflow. This is not the empty-final-response variant from #32389: Codex emits a normal, visible, non-empty progress/result message, but the overall approved task and current implementation stage are still incomplete.
Environment
openai.chatgpt)019f6725-60b5-7852-ad86-6c329eb3c2d4The behavior was seen both in the VS Code extension and in the Codex desktop application, so it does not appear to be specific to the VS Code UI layer.
Workload and instructions
The agent was implementing a Laravel/Vue project from a fully prepared implementation plan. The prompt explicitly required it to:
There was no GitHub Actions loop in this clean reproduction; checks were local. Context was also not exhausted.
Observed pattern
After an initial substantial run, Codex repeatedly performed a small valid implementation step, often committed and pushed it, then emitted a visible progress/result message and ended the turn while the same stage remained incomplete.
Representative examples:
TaskTypeplus one test, then stopped;Taskmodel/migration, then stopped;Manual follow-ups such as
continueimmediately resumed work. The same pattern recurred many times in the same conversation.The agent was also explicitly asked to self-diagnose the premature stops. It correctly stated that it had been treating a successful local step or commit as a natural response boundary, but the next turn still ended after another tiny implementation step.
Client-log evidence
The captured VS Code
Codex.logcontains 16 separate turn starts for the same conversation. For each turn we recorded the exact start time,turnId, and return to idle/read state.The client log does not show a genuine external blocker, fatal error, or an explicit user-visible reason for ending. It also does not expose
needs_follow_up,model_needs_follow_up, or a usefulstopReason, so server-side telemetry will likely be needed.Useful IDs include:
019f6725-60b5-7852-ad86-6c329eb3c2d4019f6770-0a1f-7661-a441-8dd66954fdd2019f6771-1d38-7130-9328-0500db7c4c62Evidence package
A sanitized evidence package is available in this public repository:
59a254ad3993fd184b697e991f47c31099818a5cExpected behavior
When the current stage and overall task remain incomplete, the agent has an explicit next action, tools remain available, and no genuine external blocker exists, a successful local step/commit should not be accepted as the terminal boundary of the turn. Codex should continue with the next planned tool call or provide a real blocking/final response.
Actual behavior
Codex repeatedly turns small successful implementation checkpoints into terminal user-visible responses and waits for another manual
continue, despite explicit instructions to proceed through the remaining stages.This appears consistent with the core issue described here, but adds a cross-client GPT-5.6 Terra reproduction with non-empty visible final messages, no subagent dependency, repeated occurrences in one session, and complete client-side evidence.
Same-session A/B comparison: GPT-5.6 Terra vs GPT-5.6 Sol
I now have a stronger controlled reproduction from the same Codex session, repository, task, client, OS, and reasoning level. The only variable changed was the selected model.
Environment held constant
openai.chatgpt26.707.71524019f6725-60b5-7852-ad86-6c329eb3c2d4GPT-5.6 Terra result
With GPT-5.6 Terra, the session repeatedly ended after small successful local steps, commits, migration fixes, or partial-stage checkpoints. The visible message often described future work, but the turn stopped and required a manual
continueto resume. This happened many times in the same session.GPT-5.6 Sol result
After switching only the model to GPT-5.6 Sol and sending one initial
continue, Codex completed the remaining stages 5-14 without any further user prompt.The single continuous run:
2026-07-16 00:10:50local time2026-07-16 03:41:47local time3h 30m 57s019f679e-3690-76d0-a570-4a8bfc149a21It completed the full acceptance pass and pushed final commit:
b0c11075766a4c32e50e9e4514f5d1f1cd255306Reported verification included backend tests, browser E2E, TypeScript/ESLint/Prettier/Vite, Pint/PHPStan, security audits, OpenAPI validation, clean install and upgrade on MySQL 8.4, Redis/search/access/localization checks, and a backup/restore drill.
This does not prove the exact server-side mechanism, but it is a strong model-dependent A/B result: Terra repeatedly treated local subtask completion as a terminal turn boundary, while Sol completed the rest of the same approved task continuously in the same session.
Public evidence
The client log does not appear to expose the selected model name directly, so the screenshots establish the Sol/Medium selection while the timestamps, shared conversation ID, turn ID, and UI duration correlate the continuous run.
Additional reproduction: reasoning-only completion followed by commentary-only completion
I reproduced this twice on Codex CLI
0.145.0.289. This variant adds run-loop telemetry showing that Codex itself classified the malformed terminal shape as not needing follow-up.Sequence
241,688 / 258,400input tokens, a long-running turn received a protocol-complete response containing only areasoningitem. The rollout immediately recordedtask_completewithlast_agent_message=null.phase=commentaryassistant message promising to continue, but no tool call or final answer. Codex again immediately recordedtask_complete.238,116 / 258,400input tokens.For the second reasoning-only completion,
codex_core::session::turnlogged:The commentary-only follow-up similarly logged
model_needs_follow_up=falseandneeds_follow_up=false.This was not output-token truncation or an incomplete transport stream: the response was protocol-complete. Automatic compaction later reduced the context to
7,449tokens, after which normal tool use resumed. A later compaction reduced it to17,763; large tool outputs grew the context back to238,116, and the failure recurred.Context saturation appears to be the model-side trigger, but the client-side robustness issue is deterministic: a completed response containing only reasoning, or only a commentary-phase progress message, is accepted as terminal because no tool call set
model_needs_follow_up=true.Useful regression cases would assert that:
task_complete; andphase=commentaryassistant message without a final-phase message or tool call does not publishtask_complete.I can provide sanitized rollout excerpts privately if useful.
Automated Codex reproduction report — posted on behalf of @cconkrig
This comment was generated and posted by Codex after directly inspecting the affected Codex Desktop task states and timestamps. The user explicitly authorized this follow-up.
The newer report #36506 appears to be the same core turn-finalization defect tracked here, rather than the child-lifecycle-specific case in #36141. It adds the following evidence:
26.727.6591.0, product/file version150.0.7871.18210.0.26200.0completedand the task toidlewhile the Goal still had eligible work250,965 ms,262,043 ms,159,666 ms, and a subsequent fresh reproduction at259,995 msThis strengthens the existing regression case: a
phase=commentarymessage with future-action intent must not be accepted as a terminal turn boundary while a persistent Goal remains active. If an owned command is live, its ownership/result also needs to survive any automatic continuation boundary.No repository names, paths, credentials, database details, task IDs, or private prompts are included here. The fuller sanitized report is #36506, which will be closed as a duplicate of this issue.