Repository navigation
Codex App: goal auto-continuation creates hundreds of empty turns, then history failure renders an infinite blank timeline #45864
Description
What version of the Codex App are you using (From “About Codex” dialog)?
26.908.70816 (build 9275), app commit 040e17b4b5541aff122f8382ebb57cf6f6eda815
What subscription do you have?
ChatGPT Pro
What platform is your computer?
Darwin 24.6.0 arm64 arm
What issue are you seeing?
A local Codex task shell loads (title, project metadata, goal panel, composer, and usage-limit banner), but the central conversation timeline stays blank/loading indefinitely. Native navigation succeeds. Forking the task reproduces the blank timeline because the fork inherits the affected history.
There was no Electron renderer crash, OOM, JSONL syntax error, or relevant thread/read error in local logs.
The valid rollout had grown to:
- 7,718 JSONL records
- 25,033,231 bytes
- 567 turns
- 1,502 projected UI items
- 133,861,317 tokens recorded for the polluted thread
After the last meaningful completed turn at rollout ordinal 3007, goal auto-continuation produced 562 completed turns whose agentMessage.text was exactly empty, plus empty reasoning/service events, until usage_limit_exceeded. There were no user messages or meaningful assistant messages after ordinal 3007.
The installed renderer contains an additional visible failure mode. In webview/assets/local-conversation-thread-fe391f4932ed.js, LocalConversationThread accepts hasInitialHistoryLoadFailure, and the page passes that state, but the component does not use it. When initial history loading fails, the terminal condition continues to render the loading skeleton rather than an error/retry state. This matches the observed indefinitely blank timeline.
I am intentionally not posting the private conversation contents or full local session ID in this public issue. I can provide sanitized diagnostics privately if needed.
What steps can reproduce the bug?
- Create a tracked goal in a long-running local Codex App task.
- Let it accumulate a substantial conversation/tool history.
- Explicitly stop the work while the goal auto-continuation mechanism remains present.
- Observe the goal mechanism repeatedly starting and completing turns with empty assistant messages instead of honoring the stopped terminal state.
- Continue until the account reaches
usage_limit_exceeded. - Reopen the task in Codex App.
- The task chrome loads, but the central conversation timeline remains indefinitely blank/loading.
- Fork the task: the fork inherits the polluted history and fails the same way.
Local recovery confirmed the data trigger:
- Back up the rollout and SQLite state.
- Truncate only the empty auto-continuation tail after ordinal 3007.
- Rebuild only this thread’s
thread_items,thread_turns, and projection state. - Keep the goal
usage_limitedso it cannot restart the loop. - The native thread reader immediately returns the two preserved meaningful turns and 856 items, and the timeline can be reopened.
No user messages or meaningful assistant output existed in the removed tail.
What is the expected behavior?
- Goal auto-continuation must stop after an explicit user stop/final answer and must not emit repeated empty completed turns.
- History loading should be bounded/paginated and tolerate large valid histories.
LocalConversationThreadshould renderhasInitialHistoryLoadFailureas a visible error with retry/recovery instead of an infinite blank skeleton.- Fork should rebuild/compact a failed or overgrown projection rather than blindly reproducing it.
Additional information
The rollout itself remained valid JSONL and the projection reached EOF before repair, so this was not file corruption. The visible failure was caused by unbounded empty goal-turn generation plus the UI swallowing the initial history-load failure.
Nearby existing issues discuss oversized rollouts or general unbounded session state, but I did not find one covering this exact combination of empty goal auto-continuation turns, fork inheritance, and the ignored hasInitialHistoryLoadFailure state.
Activity
github-actions commentedon Sep 16, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
razdgann commentedon Sep 16, 2026
The 562 empty completed turns suggest two independent guards are needed: stop continuation after an explicit terminal state, and treat repeated empty assistant outputs as a circuit-breaker condition rather than successful progress.
I’d also give every continuation a parent goal ID and attempt number, then record token/cost usage even when the visible output is empty. That makes the waste measurable and lets recovery compact only the failed tail. ModelGate uses this parent/attempt accounting so “no output” cannot look like “no work billed.”
https://github.com/razdgann/modelgate-oss or https://modelgatehq.com/