Codex Desktop meta-bug: unbounded session/turn state causes freezes, context bloat, and lost active-turn control

Open 💬 8 comments Opened Jun 2, 2026 by FromAriel
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of the Codex App are you using (From “About Codex” dialog)?

26.527.60818

What subscription do you have?

pro

What platform is your computer?

Microsoft Windows NT 10.0.19045.0

What issue are you seeing?

Codex Desktop meta-bug: unbounded session/turn state causes freezes, context bloat, and lost active-turn control

Suggested labels

bug, app, session, context, tool-calls, performance, app-server

Summary

Several open Codex issues appear to be different symptoms of the same larger reliability problem:

Codex Desktop allows local session/turn state to become unbounded, then places that state on hot UI, resume, context assembly, IPC, and active-turn ownership paths. Once a thread is long-running, tool-heavy, image-heavy, repeatedly compacted, or has experienced renderer/restart/interrupt recovery, the app can freeze, become extremely slow, overfill context, lose trace/progress visibility, fail Stop/cancel, or continue backend work while the UI appears stuck in Thinking.

I do not think every linked issue is the same single code bug. The clearer framing is one parent/meta bug with several fix surfaces:

  1. unbounded persisted rollout/session records;
  2. full-history hydration into app-server/client/renderer state;
  3. context replay/compaction retaining large tool or image payloads;
  4. renderer/app-server turn ownership and trace-stream rehydration losing authority;
  5. insufficient diagnostics, because very different waits all collapse into Thinking, Working, or Reconnecting.

Evidence from related open reports

1. Large local rollout/history hydration makes Desktop slow, frozen, or unrecoverable

  • #18693 reports a verified A/B profile test where a copied profile is smooth until only a few giant local histories are restored. Largest anonymized rollouts were about 455 MiB, 507 MiB, 561 MiB, 584 MiB, and 1867 MiB; operations such as resume/read/unsubscribe could take tens of seconds, with worst cases around 82s.
  • #20269 reports a long-running Windows Desktop task producing a 718.6 MB rollout JSONL with 3,305 lines. After force quit, every launch auto-resumed the oversized session and froze. Renderer CPU was around 140% of one core and working-set memory grew by about 1.177 GB in 10s.
  • #22991 reports multiple long-running session files around 500 MB or larger. The strongest freeze occurred not merely when opening a large conversation, but when sending a new prompt in an already-open large thread.
  • #11984 is the long-running umbrella report for Desktop UI lag during long sessions. Later comments tie the problem to full history hydration, renderer CPU/RSS, and large IPC/app-server payloads rather than only DOM rendering.
  • #21299 reports Windows long-thread message submit lag: sending a new message in a long thread makes the app unresponsive for about 5s, and pruning old local JSONL session files is reported as a workaround.

2. Hard size limits and inline payloads expose the same design failure

  • #22004 reports a reproducible Electron main-process crash, RangeError: Invalid string length, when loading sessions whose rollout JSONL exceeds V8's max string length. Reported sizes include 506.8 MB, 786.7 MB, 963.5 MB, 1050 MB, and 1601 MB. Related comments report an 825 MB rollout producing a dropped 405 MB IPC payload, and a macOS 1.37 GB rollout where app-server grew to 6-8 GB RSS.
  • #24676 shows that the problem can occur below the hard 512 MB crash threshold. A 182.8 MB image-heavy rollout had 41,361 lines, a max JSONL line of 6,850,815 chars, and many inline image_url / payload.images records. A newer repro was only 102.44 MB, but almost the whole file was data:image payloads; a compacted record alone was 24.207 MB with 16 image references.
  • #22091 reports Desktop context growth from retained tool outputs: a fresh session reached 137,293 / 258,400 tokens after a small number of visible interactions, and an earlier diagnostic reached 234,757 / 258,400, then re-inflated after compaction. Several retained tool outputs were around 37K-40K characters each.

3. Context compaction/replay can amplify the same state bloat

  • #25009 reports Desktop becoming slow or stuck after context_compacted events and approval transcript injection. The report found repeated approval assessment / TRANSCRIPT DELTA blocks containing prior tool calls, tool outputs, retry reasons, and planned actions.
  • #24095 tracks Windows memory spikes and freezes after repeated context compactions in a single long-running session, distinguishing this from one-time renderer regressions or image-only rollouts.
  • #19842 reports Codex CLI running out of context instead of compacting/resuming a long tool-heavy thread. One tool output had an original token count of 815,104; the final token-count event reached 258,400 / 258,400.
  • #19585 is nominally about usage depletion, but the useful overlap is the "compaction tax": failed/slow compaction and repeated reconstruction consume additional usage and make long-session failure more expensive.

4. Active turn ownership and renderer/session state can desynchronize

  • #24287 reports the dangerous control-plane symptom: prompt accepted, UI stuck in Thinking, Stop fails or is misleading, progress traces disappear, and backend usage can continue decreasing while no activity is visible. It also reports multi-window rehydration making already-visible traces disappear and state disagreements between the goal bar, prompt box, and chat/trace area.
  • #24434 reports a post-tool continuation stall: pwd and rg --files returned successfully almost instantly, then no assistant message, no new tool call, and no task completion occurred for about 6m59s until manual interrupt.
  • #24263 gives concrete renderer rehydration evidence. After a renderer reload, logs showed placeholder latest-turn rebinding, completed turns marked markedStreaming=true, Received turn/started for unknown conversation, and 5,466 Item not found in turn state errors in one Desktop log.
  • #23644 reports composer submit timing out after stale conversation state accumulated over several days. Local app-state snapshots included pending_request_count=20, thread_count_active=15, thread_count_streaming_owner=6, thread_count_streaming_without_active_runtime=13, item_count_total_loaded=22550, and about 201 MB of estimated delta bytes. Restart cleared the issue.
  • #23035 reports an orphan task_started without task_complete poisoning reopen/resume. The rollout parsed cleanly, but balancing the orphan turn with a synthetic completion made the lifecycle valid again. This suggests interrupted/failed turns need durable terminal state or tolerant resume logic.
  • #21360 reports multiple turn lifecycle stall modes: task_started without task_complete, tool outputs returned without assistant continuation, and long non-image sessions with multiple compactions and unfinished turns.

5. Transport/first-output stalls are adjacent and currently indistinguishable in the UI

Some reports may not share the same local-history root cause, but they matter because the UI collapses them into the same stuck state and recovery paths can interact with renderer/session state:

  • #24260 reports a gpt-5.5 xhigh turn accepted immediately, then 30m38s before the first persisted reasoning item. Later comments include responses_http idle spans of hundreds of seconds and a packet-capture case where a reused connection was reset but recovery waited for the 300s stream idle timeout.
  • #24414 reports the VS Code extension staying on Thinking for minutes even for simple prompts.
  • #24419 reports CLI Working hangs and reconnect retries; interrupting and resubmitting the same prompt can run normally.

These may require separate transport/request watchdog fixes, but the Desktop issue should still distinguish them from renderer detachment, post-tool continuation stalls, and full-history hydration.

Suspected root cause family

The common design problem seems to be that "thread state" is doing too many jobs at once:

  • durable audit log;
  • UI transcript;
  • context replay source;
  • app-server resume payload;
  • renderer live state;
  • trace/progress stream state;
  • tool output/image artifact store;
  • recovery source after restart or renderer reload.

When those roles are all served by unbounded JSONL and large in-memory turn arrays, one oversized or inconsistent thread can poison many surfaces.

Requested fixes / invariants

Bound persisted session records

  • Cap persisted function_call_output, custom tool output, event_msg payloads, and InputText/image fields before they enter rollout JSONL.
  • Do not persist raw data:image / base64 image payloads in normal rollout records or compacted.payload.replacement_history; use file/blob references, hashes, or placeholders.
  • Avoid duplicating the same image/tool payload across both response_item and event_msg.
  • Add rollout size warnings and automatic safe repair/export paths.

Make thread loading lazy and paged

  • thread/read, thread/resume, thread/turns/list, stream-state snapshots, and sidebar state should have hard byte/count caps.
  • Opening a thread should return metadata and a recent bounded tail, for example the most recent 100-200 messages or a small byte cap.
  • Older turns, heavy tool outputs, and images should load only on scroll/expand.
  • Transcript rendering should be virtualized, but virtualization alone is insufficient if full history is still hydrated into renderer/app-server state.

Separate context assembly from durable transcript history

  • Context compaction should summarize or reference old heavy content instead of replaying raw tool outputs/images.
  • Approval transcript or retry transcript injection should be bounded and deduplicated.
  • Context/token accounting should expose whether growth came from visible user text, hidden tool output, compaction replacement history, approval transcript injection, or old transcript replay.

Make active-turn ownership durable and recoverable

  • Persist a turn record and its originating thread before streaming begins.
  • Persist accepted user prompts before upstream/network submission.
  • On renderer reload/restart, reattach by durable turn id and event cursor, not just in-memory renderer state.
  • Stop/cancel should resolve to an explicit state: cancelled, still running remotely, already completed, failed to cancel, or unknown/detached.
  • If backend active turns exist without renderer ownership, show a recovery banner and reattach option.

Make resume/reconciliation authoritative

  • A terminal backend turn must not rehydrate as markedStreaming=true.
  • If a renderer receives item deltas for an unknown conversation, it should buffer briefly and force a thread/turn re-read instead of dropping state and spamming Item not found in turn state.
  • On resume, reconcile the full item id set for the active/recent turn before applying live deltas.
  • Orphan task_started turns should be repaired as interrupted/failed during resume rather than crashing LocalConversationPage.

Improve diagnostics

  • Add phase-specific timing/log events for: request accepted, upstream request sent, response headers received, first byte, first Responses event, first assistant/reasoning/tool item, tool result returned, post-tool continuation requested, context compaction started/completed, renderer attached/detached, and Stop/cancel result.
  • Keep performance traces locally if upload fails (#24262).
  • Preserve enough local diagnostics to tell whether a stuck turn is model/backend stall, transport retry, context compaction, app-server hydration, renderer detachment, or post-tool continuation loss.

Related issues

Large history / full hydration:

  • #11984
  • #18693
  • #20269
  • #21299
  • #22991

Hard size limits / image or tool payloads:

  • #22004
  • #24676
  • #22091

Context compaction / context replay / usage amplification:

  • #19842
  • #19585
  • #24095
  • #25009

Turn lifecycle / UI ownership / trace and Stop desync:

  • #21360
  • #23035
  • #23644
  • #24263
  • #24287
  • #24434

Adjacent transport / first-output stall reports that should be distinguished in diagnostics:

  • #24260
  • #24414
  • #24419

Potentially adjacent Desktop lifecycle reports:

  • #22655
  • #25094
  • #21076

Why this should be tracked as a meta issue

Individual reports often look like separate bugs because the immediate symptom differs: slow thread switching, V8 string crash, image-heavy freeze, compaction memory spike, stuck Thinking, invisible active turn, failed Stop, composer timeout, missing tool traces, or CLI/extension first-output stalls.

But the recurring evidence points to one architectural boundary that needs a coordinated fix: Codex should treat durable history, model context, renderer transcript, live turn stream, and recovery state as separate bounded contracts. Until those contracts are bounded and authoritative, fixes to only one surface, such as rendering virtualization or a single timeout tweak, are likely to leave other variants open.

What steps can reproduce the bug?

User-visible failure modes

  • Desktop becomes slow or unresponsive when opening a long thread, switching threads, sending a new prompt in an old thread, or after repeated context compactions.
  • The app can become unrecoverable on launch if the most recent session auto-resumes an oversized rollout.
  • A short follow-up in an old session can freeze the UI even though a fresh session still works.
  • Tool outputs can return successfully, but the assistant continuation never resumes.
  • A prompt can be accepted and backend work can continue, while the Desktop UI stays stuck in Thinking and no progress traces appear.
  • Stop/cancel can become unavailable, misleading, or ineffective because the UI has lost the active turn reference.
  • After restart or renderer reload, prompts/traces/tool calls can be missing, stale, or only partially recovered.
  • The same root state bloat can also drive fast context growth and usage drain through retained tool output, compaction history, and replayed approval/diagnostic transcripts.

What is the expected behavior?

Expected behavior

  • Opening or switching to a thread should load metadata plus a bounded recent tail, not the entire transcript/tool/image history.
  • Sending a short prompt in an old thread should not synchronously parse, render, serialize, or replay hundreds of MB of session data.
  • Context compaction should reduce active prompt pressure and should not retain raw large tool outputs, image data, or repeated transcript-injection blocks.
  • Rollout JSONL should not store raw image bytes or unbounded tool output inline when references, caps, summaries, or external artifacts would work.
  • If one thread is too large or malformed, Desktop should fail that thread safely while leaving the rest of the app usable.
  • If a prompt is accepted, the originating thread should durably show the user prompt, trace/progress stream, and Stop/cancel state.
  • If the renderer loses ownership of an active backend turn, it should show an explicit recovery/reattach state rather than generic Thinking.
  • Terminal backend states should be authoritative: completed, failed, interrupted, or cancelled turns should not rehydrate as streaming.
  • Tool-returned, waiting-for-first-output, reconnecting, context-compacting, renderer-detached, and post-tool-continuation-stalled states should be distinguishable in UI and logs.

Additional information

_No response_

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 1 month ago

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

  • #24510
  • #25390
  • #24676
  • #24336
  • #24434

Powered by Codex Action

lzy18001500226 · 1 month ago

I can add another Windows Desktop datapoint that seems to fit this meta-bug.

In a long-lived Windows-native Codex Desktop workspace with many visible project threads, large transcripts, frequent cross-thread dispatches, context compaction events, interrupted turns, and recurring automations, individual threads can remain listable/readable while new turns fail to start or settings updates fail with errors such as:

failed to update thread settings: internal error; agent loop died unexpectedly
failed to start turn: internal error; agent loop died unexpectedly
Error submitting message

The important distinction is that fresh/empty threads can still accept simple messages, and restarting Codex Desktop / Codex++ often temporarily restores the same affected visible thread. So this does not look like a global account/network failure or a project-specific runtime failure. It looks more like stale or inconsistent thread/conversation/app-server state after long-lived multi-thread usage.

Local scale indicators from the affected workspace:

about 144 total thread records
about 120 project thread records
largest orchestration transcript around 532 MB
operations/patrol transcript around 173 MB
diagnostic history around 701 MB
repeated context compaction / interrupted / markedStreaming=true style evidence in local logs
Related surface also overlaps with #23971, but our trigger is not only subagent close; it is broader Windows Desktop long-lived visible-thread dispatch/start-turn degradation.

A useful product-level fix would be to expose a clearer per-thread state, for example: readable/listable but not routable, approval pending, compaction pending, stale runtime, or agent-loop failed. Right now those states can collapse into the same practical outcome: the thread looks present but cannot be safely used for automation or dispatch.

ooiuuii · 1 month ago

Adding a Windows Desktop data point that seems to fit this meta-bug, especially the distinction between local runtime stalls and degraded thread/session state.

In my case, two problems initially looked like the same "Codex is stuck" symptom, but they turned out to be different layers:

  1. One project under a OneDrive-backed Documents/New project path was genuinely I/O-bound. A pnpm install had produced a partially built node_modules with about 90,910 files / 2.8 GB, and the project also had .worktrees around 250,160 files / 6.23 GB plus .git around 2.44 GB. Moving/cloning the active repo to a non-synced F:\openclaw\repos\... path made the dependency install finish in about 17s and Vite become ready in about 2s.
  1. A separate old Codex Desktop thread was not explained by local I/O. At diagnosis time there was no active shell, pnpm, gh, or similar subprocess, local CPU/RAM pressure was low, and the thread was already near the effective context window at about 232k / 258k tokens. It had accumulated large prior diagnostic/tool output (doctor --fix, rg, gateway checks, etc.). That thread remained unsafe to continue even after the workspace I/O issue was fixed, so I abandoned it and continued from a short-context thread.

The useful distinction for this issue is: Desktop should not make these both look like generic Thinking/stuck states. It would help if the app could expose whether the current stall is:

  • a live local subprocess;
  • a post-tool continuation stall after subprocess completion;
  • app-server/thread hydration or renderer reattachment;
  • context compaction / near-window pressure;
  • model/Responses stream waiting for first output;
  • local workspace I/O risk from OneDrive/cloud-sync and huge file counts.

The product-level recovery also needs to be different. Moving the repo out of OneDrive fixes the I/O stall, but it does not rescue a degraded long-context thread. For that second case, Codex needs a safe fork/handoff/degraded-session path rather than encouraging the user to keep prompting the old thread.

I filed the narrower diagnostic-boundary issue as #28345, so this comment can stay focused on how the datapoint fits the broader session/context meta-bug.

nasadunadu · 9 days ago

Adding a macOS data point with a concrete IPC hard-limit failure from an oversized local rollout.

Environment

  • macOS (Apple Silicon)
  • Codex Desktop: 26.707.41301 (build 5103)
  • Renderer: 150.0.7871.115
  • Bundled CLI / app-server: 0.144.0-alpha.4

Local state before mitigation

  • active Codex data: approximately 5.4 GB
  • active sessions: approximately 1.3 GB
  • archived sessions: approximately 2.6 GB
  • largest rollout files: approximately 902 MB, 574 MB, and 350 MB

The thread list itself remained fast (about 276 ms). Reading recent/light threads took about 165-393 ms. The 574 MB and 902 MB histories took about 1.26 s and 1.95 s for a bounded recent read.

However, reading the approximately 350 MB history failed after about 2.8 seconds with a concrete IPC frame error:

code-mode delegate response exceeds the IPC frame limit: code-mode IPC frame length 81989668 exceeds 67108864 bytes

This occurred even when the caller requested a bounded recent read and set output inclusion off. The returned payload path still attempted to construct approximately 82 MB for a protocol with a 64 MB single-frame limit.

Mitigation result

Moving old oversized rollouts out of the hot scan path reduced the active Codex directory from about 5.4 GB to about 2.0 GB and improved general responsiveness. The histories were preserved in a verified compressed cold backup. This is an effective local workaround, but users should not need to manually manage internal JSONL files to keep Desktop usable.

Requested invariants

  • hard byte/count limits before app-server or code-mode responses enter IPC
  • honor bounded reads and output-exclusion options across every response layer
  • replace inline heavy tool/image payloads with references or explicit expandable placeholders
  • show rollout-size warnings before a thread approaches renderer/V8/IPC limits
  • provide a supported archive/export/repair workflow for oversized histories
  • one oversized thread should fail safely without degrading navigation or other threads

I have omitted local paths, thread IDs, raw conversation content, account data, and credentials.

wherewolf87 · 9 days ago

Adding a Windows Desktop datapoint with a deterministic failure on one oversized, long-lived thread.

Environment

  • Codex Desktop for Windows: 26.707.3748.0
  • Windows 11 x64
  • Subscription: Pro

Local evidence

  • The affected rollout is 455.67 MiB with 43,086 JSONL records.
  • Its last persisted turn reached task_complete; the thread remains present and listable.
  • Recent token events reached the five-hour window's 100% marker while the in-flight turn continued to its terminal event.
  • The UI then showed a usage-limit message, but submitting a follow-up surfaced only generic internal-error UI.

Reproduction

  1. Open the affected long-lived thread.
  2. Submit a short follow-up such as continue working.
  3. The UI shows Error submitting message and/or a red Error creating task toast.
  4. Reproducing through the Desktop thread API without a model override returns:

failed to start turn: internal error; agent loop died unexpectedly

  1. Reproducing with a lower-cost model override fails before the turn starts with:

failed to update thread settings: internal error; agent loop died unexpectedly

  1. A same-directory fork attempt does not complete successfully.

The original rollout remains parseable and its prior terminal event is intact. No active local subprocess explains the failure.

Expected behavior

  • A usage or model quota rejection should surface as a precise rate-limit response, not agent loop died unexpectedly.
  • A completed oversized thread should remain safely routable through bounded/lazy state, or the app should offer a supported compact continuation that does not copy the entire hot history.
  • Switching to an available lower-cost model should either start successfully or return the actual account/model limit.
  • A fork should fail with an actionable size/state error rather than aborting generically.

This appears consistent with the meta-bug's unbounded history plus thread-routing failure family, while also exposing a misleading usage-limit-to-internal-error mapping.

uatragada · 9 days ago

Additional Windows evidence from July 11, 2026. This variant presents as repeated full Desktop process exits/relaunches, not only an in-place renderer reload.

Environment

  • Windows 11 Home, build 26200, x64
  • Codex Windows Store package: OpenAI.Codex_26.707.3748.0_x64__2p2nqsd0c76g0
  • Separate installed CLI: codex-cli 0.144.1
  • Multiple concurrent active threads/turns; in-app browser/sidebar activity was present

Observed process lifecycle

The Desktop logs show several sessions ending abruptly without the normal:

[AppServerConnection] Stopping app-server transport

A new Desktop process was then launched shortly afterward:

PID 34408: last log 2026-07-11T21:05:06.363Z
PID 50052: Launching app 2026-07-11T21:05:10.822Z

PID 50052: last log 2026-07-11T21:44:59.471Z
PID 26268: Launching app 2026-07-11T21:46:34.140Z

PID 26268: last log 2026-07-11T22:14:37.615Z
PID 27812: Launching app 2026-07-11T22:14:41.165Z

The third sequence ended immediately after stale-conversation events and browser-sidebar teardown:

2026-07-11T22:14:37.114Z error Received item/started for unknown conversation conversationId=<redacted>
2026-07-11T22:14:37.386Z error Received item/completed for unknown conversation conversationId=<redacted>
2026-07-11T22:14:37.615Z info IAB_LIFECYCLE renderer removed browser sidebar webview ... tabType=web
<log ends>
2026-07-11T22:14:41.165Z info Launching app ... platform=win32

Error volume before exits

Main-process/Desktop logs for the affected runs contained:

Session PID 34408 (3h45m):
  errors: 138
  warnings: 248

Session PID 50052 (40m):
  errors: 502
  warnings: 93

Session PID 26268 (28m):
  errors: 1,729
  warnings: 91

Session PID 27812 (16m):
  errors: 728
  warnings: 137

Across these sessions, the dominant error categories were:

1,092  Received item/completed for unknown conversation
1,084  Received item/started for unknown conversation
  688  Conversation state not found
  142  ResizeObserver loop completed with undelivered notifications
   41  Received turn/started for unknown conversation
   34  Received turn/completed for unknown conversation

One affected session started emitting Received turn/started for unknown conversation only seconds after startup while other threads were actively streaming. Subsequent events for that conversation continued for the life of the process.

Negative evidence

  • No matching Windows Application Error / Windows Error Reporting record
  • No Codex/Electron dump in the package Crashpad paths
  • No WER report archive entry
  • Sentry queue was empty
  • No evidence of an out-of-memory condition:
  • approximately 17 GB physical memory available
  • approximately 21 GB committed against a 63 GB commit limit

This makes system memory pressure and a conventional WER-captured native crash unlikely.

Assessment

This appears consistent with the active-turn/renderer state desynchronization family tracked here and in #24263, but this instance escalates into repeated full Desktop process termination/relaunch. The strongest trigger correlation is multiple concurrently streaming threads plus browser/sidebar lifecycle activity. Exact reproduction is still timing-sensitive.

Useful fixes/diagnostics would include:

  • buffering/reconciling events for an unknown conversation instead of continuously applying and logging them;
  • recording an explicit main/renderer exit reason before relaunch;
  • preserving Crashpad/Sentry evidence for these exits;
  • making browser-sidebar teardown safe while active or detached turns still exist.
hug1997 · 6 days ago

Additional macOS reproduction from Codex Desktop release 26.707.72221 / bundled CLI 0.144.2:

Fresh image thread stalled before first output

  • A brand-new local thread was created with two ordinary PNG attachments (~466 KB and ~1.4 MB).
  • Actual thread ID: 019f5fe0-c206-7100-89a8-05c9dc96e3e9.
  • Desktop accepted turn/start in ~29 ms.
  • In the same second, the Desktop log emitted:

Received turn/started for unknown conversation
with conversation ID 019f5fe0-c309-7851-a255-c58d8a12d928, which did not match the actual thread ID.

  • After the accepted turn/start, there was no persisted reasoning item, assistant message, tool call, completion event, or explicit error.
  • The UI remained active / inProgress until the turn was manually interrupted roughly 3 minutes later.
  • Fully quitting and restarting Codex cleared the stale behavior.

The unknown conversation event is correlated with the stall but is not proven to be the root cause. It may indicate a thread/turn routing or renderer reattachment race. The important user-facing issue is that the app exposed only a generic active/thinking state and no recoverable phase-specific error.

After restart, the image pipeline completed again but remained very slow: 130.7 seconds cold and 45.4 seconds warm for a trivial one-line response. That controlled performance reproduction is tracked in #33018.

No private image content or raw logs are included in this comment.

qihangzhang-272 · 5 days ago

Adding a reproducible Windows Desktop datapoint with a same-version CLI control test.

Environment:

  • Codex Desktop (Microsoft Store): 26.707.9981.0
  • bundled/local CLI: codex-cli 0.144.2
  • Windows x64
  • Pro subscription
  • affected rollout uses history_mode=legacy

Observed failure:

  • The affected thread remained readable through the paged thread-read path and its most recent turn was completed.
  • The original working directory still existed.
  • The rollout was 108,119,172 bytes and 4,190 JSONL lines before the control test.
  • SQLite reported 107,493,536 cumulative tokens for the thread; the last completed turn used about 57.6k tokens against a 258.4k context window, and the weekly rate limit was only about 11% used.
  • Starting a new turn through the Desktop/background follow-up path failed twice with:
failed to start turn: internal error; agent loop died unexpectedly
  • On each Desktop failure, the new prompt was not appended to the rollout JSONL. The composer text remained present in local draft state.
  • Retrying after a successful CLI resume still failed in Desktop, so the CLI control did not repair the Desktop path.

Same-version control:

  1. Exit any temporary resume process.
  2. From the thread's real working directory, run:
codex resume <redacted-thread-id>
  1. Send a no-tool diagnostic prompt.
  2. The same CLI version (0.144.2) successfully loaded the 108 MB history and returned the requested short response.
  3. Exit the TUI cleanly.
  4. Retry the same short prompt through Desktop/background follow-up: it again fails with agent loop died unexpectedly.

This narrows the failure to the Desktop/background agent-loop lifecycle or thread-loading/ownership path rather than the model, account quota, working directory, rollout parseability, or core direct-resume capability.

Additional signals:

  • One earlier turn in the rollout had task_started without a matching task_complete, although later turns completed successfully, so stale lifecycle state may be a contributing factor.
  • At the time of one failed Desktop attempt, structured logs also contained failed to refresh available models: timeout waiting for child process to exit after the models HTTP request itself returned 200. I cannot prove this is causal.
  • The user observed several threads becoming unable to submit messages around the same time. Local app state contained multiple non-empty composer drafts, but only this thread was tested end-to-end.

Expected behavior:

  • Desktop should resume/start the turn as the direct CLI path does, or fail with a recoverable per-thread error.
  • Accepted composer text should be durably persisted before agent-loop startup so a worker failure cannot silently drop the attempted turn.

Privacy:

  • Thread ID, username, workspace path, prompt contents, and credentials are intentionally redacted.
  • The raw rollout cannot be attached because it contains private project history.

Related exact error family: #23971. Related long-history/direct-resume behavior: #25215 and #25430. A recent minimal report with the same message was #33206.