Codex desktop thread remains active/inProgress after interrupted turn with no agent output
What version of Codex are you using?
Codex Desktop App, version not captured from the app UI during diagnosis.
Which platform are you using?
macOS desktop app.
What happened?
A Codex desktop thread became stuck in an active state with the latest turn marked inProgress, but there was no visible agent response, no tool call, and no command output.
The affected workspace was:
/Users/wangerpan/Desktop/星瞰
That workspace is not a git repository.
Affected thread details observed through Codex thread inspection:
sourceThreadId: 019ece63-2408-7d62-ad54-092a7a6365a7
stuckTurnId: 019ecfb5-8858-73e0-abca-a29f8496ca00
userMessage: 为啥卡住了
threadStatus: active
turnStatus: inProgress
completedAt: null
durationMs: null
The immediately previous turn had been interrupted:
previousTurnId: 019ecfb1-d488-7601-8c87-18c99db0b4e7
previousStatus: interrupted
previousDurationMs: 238320
After that interrupted turn, the next user message remained stuck in progress and the thread did not produce an assistant message, an error, or any tool activity.
Steps to reproduce
This is from a real session; exact minimal reproduction is not yet confirmed.
- Use Codex Desktop App on macOS.
- Work in a projectless or non-git workspace.
- Have a long-running turn interrupted.
- Send a follow-up user message in the same thread.
- Observe that the thread can remain
activewith the new turninProgress, while no assistant output/tool calls/errors appear.
Expected behavior
After an interrupted turn, the thread should recover cleanly. A subsequent user message should either:
- start a normal assistant response,
- show a clear error, or
- expose a user-visible way to stop/retry the stuck turn.
Actual behavior
The thread stayed active / inProgress indefinitely with no visible progress and no error.
Recovery attempts
Attempted handoff_thread on the stuck thread, but it failed because the source workspace is not a git repository:
The source thread workspace is not a git repository.
A same-directory fork_thread worked as a workaround:
newThreadId: 019ecfba-ae2b-7b73-bb84-ff8a760a335f
The fork became idle and contained completed history only, avoiding the unfinished stuck turn. The original stuck thread was archived to avoid continued use.
Additional context
This looks like the app/thread scheduler did not fully release or recover state after the interrupted turn. It would help if non-git/projectless threads had a reliable force-stop/retry path, or if interrupted turns could not leave a subsequent user turn permanently in progress.
6 Comments
Additional observation: the same-directory fork workaround did not fully resolve the problem.
The forked thread initially appeared
idle:After sending a normal follow-up message in that fork, it also became stuck:
Again, there was no assistant message, no tool call, and no surfaced error.
The forked thread also still showed older abnormal turn records from the source thread, including an
interruptedturn withcompletedAt: nulland another olderinProgressturn. So same-directory fork may not be a reliable recovery path when the source thread already has inconsistent unfinished turn state.Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
the fix everyone reaches for here is a force-stop/retry button, but the variable that actually decides recoverability is whether thread state is durable on its own. the tell is handoff_thread failing because the workspace isn't a git repo: recovery is bolted to the repo, not the session, so a projectless thread has nowhere to land after an interrupted turn. fork worked precisely because it copies completed history instead of trying to resume the poisoned turn. the axis isn't stop vs retry UI, it's whether the session is the unit of durability or the git tree is.
we ended up making the session itself the durable unit, survives restart and forks copy completed history instead of resuming a turn: https://fazm.ai/r/nh5e7t2a
I am seeing the same failure mode repeatedly in Codex Desktop, with a recent concrete case that matches this issue closely.
Environment:
26.623.101652/ build467427.0build26A5368gRecent stuck thread:
The latest turn only emitted a few commentary messages saying it was going to create a Markdown document under
docs/. After that there was no final answer and no visible tool result. I checked the repository state separately:So the agent never reached the file-writing step, but the Desktop/thread metadata still reports the thread as
activeand the turn asinProgress. This creates a zombie-running state: from the UI it looks like it may still be working, but there is no progress and no error surfaced.This has also been happening frequently in longer/heavier Desktop threads. The recurring patterns I have observed are:
view_imageoutputs are embedded into the session JSONL, causing sessions to grow very large;active/inProgressinstead of being marked failed, interrupted, or recoverable.For image-heavy cases, related issues appear to be:
But the specific problem here is the state lifecycle: even when the backend/model/tool chain stops before any side effect, Codex Desktop can leave the turn in
inProgresswith no error and no completion.Expected behavior:
Actual behavior:
active.inProgress.completedAtstaysnull.This makes recovery ambiguous and causes users to wait on a thread that has likely already stopped.
I hit the same failure mode again in Codex Desktop, including after forking the stuck thread.
Environment:
26.623.101652/ build467426.5.1build25F80Observed original stuck thread:
Immediately before that, the user sent
继续; that turn was interrupted after about 58s. Then the next in-progress turn existed with no user-visible assistant output, no tool call, no command output, and no surfaced error.I then forked the thread and saw the same pattern in the fork:
So the fork did not provide a reliable recovery path. It copied the completed history, but after sending a simple follow-up (
继续) the fork also remained active/inProgress without any assistant response or tool activity.Additional context from this case:
npm run buildcompleted successfully. Some tests were failing due to normal project-level unfinished work, but the Codex Desktop issue happened before any assistant/tool execution in the latest turn, so this looks like a Desktop/session lifecycle problem rather than a project command hang.Expected behavior:
active/inProgressafter the worker has stopped or failed to start.Actual behavior:
activewith an empty in-progress turn.activeafter a simple follow-up, with only the user message recorded.