[Desktop][Windows] Paginated thread history stalls on duplicate ordinal while rollout remains complete

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

Summary

On Windows Codex Desktop, one local paginated thread displayed only an older history snapshot although the canonical rollout JSONL still contained all later messages and the completed task. This was a local history-projection stall, not transcript deletion.

Environment

  • OS: Windows 11 x64
  • Installed Codex Desktop package: 26.820.9563.0
  • Thread-recorded runtime: codex-cli 0.149.0-alpha.4.1
  • History mode: paginated

Sanitized evidence

  • The rollout JSONL remained parseable and contained exactly one repeated ordinal: ordinal 2186 appeared twice.
  • The two records were event_msg/token_count and event_msg/thread_settings_applied.
  • thread_history_projection_state expected ordinal 2187 at the byte offset where the second ordinal-2186 record began.
  • The projection repeatedly logged an error equivalent to: expected ordinal 2187, got 2186.
  • The SQLite projection stopped at an earlier ordinal while later user/assistant records and task completion remained present in the rollout JSONL.
  • SQLite integrity checks were clean; there was no evidence of physical database corruption.
  • After backing up the files, advancing only the projection byte offset past the duplicate record while keeping the expected ordinal at 2187 allowed the projection to catch up. The canonical JSONL was not modified.

Expected behavior

When a paginated history projection encounters a duplicate boundary ordinal, Codex should reconcile or rebuild the projection from the canonical rollout, or safely skip a verified duplicate metadata record. It should not silently leave the UI permanently behind the durable transcript.

Likely cause

This appears related to duplicate ordinal assignment during restart/resume or concurrent app-server writers, combined with a projector that treats a lower ordinal as fatal and has no automatic recovery path. Related reports include #40109 and #40178. Issue #32198 is related to Windows paginated-history handling but appears distinct: it concerns legacy tool_search_output parsing/replay UI freezing, not duplicate ordinals or a frozen SQLite projection.

Requested fixes

  1. Serialize rollout writers and refresh the durable tail before assigning paginated ordinals.
  2. Detect byte-offset/ordinal mismatches on startup and rebuild or reconcile thread_history_*.
  3. Provide a supported history repair/doctor command.
  4. Surface an actionable error instead of silently showing stale history.

Privacy

No thread ID, absolute paths, prompts, conversation content, credentials, or raw logs are attached.

View original on GitHub ↗

6 Comments

github-actions[bot] contributor · 1 day ago

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

  • #40178
  • #40109

Powered by Codex Action

wangistiger-beep · 13 hours ago

Additional reproduction on Windows 10 build 19045, package 26.820.9563.0, desktop client 26.820.71523, app-managed backend codex-cli 0.150.0-alpha.8.

Read-only inspection of six affected local tasks confirms the same precise boundary pattern described in this issue: event_msg/token_count followed by event_msg/thread_settings_applied, both carrying the same top-level ordinal. The projection expects the next ordinal and stops updating.

Sanitized samples

Each row is a different task; all task identifiers and conversation content are omitted.

| Sample | Projection expects | token_count ordinal | following thread_settings_applied ordinal |
| --- | ---: | ---: | ---: |
| A | 987 | 986 | 986 |
| B | 639 | 638 | 638 |
| C | 2523 | 2522 | 2522 |
| D | 672 | 671 | 671 |
| E | 368 | 367 | 367 |
| F | 810 | 809 | 809 |

Sample A's persisted projection checkpoint is:

{"next_rollout_byte_offset":11328572,"next_rollout_ordinal":987}

Immediately before that byte offset:

{"timestamp":"2026-08-27T18:59:09.760Z","ordinal":986,"type":"event_msg","payload":{"type":"token_count"}}

At that byte offset:

{"timestamp":"2026-08-27T19:00:00.849Z","ordinal":986,"type":"event_msg","payload":{"type":"thread_settings_applied"}}

These are field-reduced excerpts; other payload fields are intentionally omitted, not empty in the source.

The repeated error is:

codex_thread_store::local::live_writer
failed to project durable rollout for <redacted-thread>:
thread-store internal error:
thread history projection for <redacted-thread> expected ordinal 987, got 986

Durable data versus visible history

  • At approximately 05:21 local UTC+08:00 on 2026-08-28, sample A contained 1,827 valid JSONL records and 23 task_started events, while its projection had only 14 cached turns. Nine subsequent turns were not represented in that cache.
  • The last cached turn began at 02:58:13 local, but the canonical rollout continued recording later user/assistant activity.
  • By the 05:38–05:39 inspection, that rollout was 22,348,289 bytes and contained a newly written assistant progress message at 05:36:46. The projection was still at byte offset 11,328,572 / expected ordinal 987.
  • After restart, thread/resume at 05:37:02 again logged expected ordinal 987, got 986. Restart did not repair the projection.
  • Read-only SQLite quick_check(1) returned ok for both state_5.sqlite and thread_history_1.sqlite. This is a structural check, not a guarantee of semantic consistency.

There are also recurring authentication-triggered sign-outs on this machine; separate evidence is being added to #39189. The projection checkpoint had already stalled before the captured sign-outs. A sign-out/restart then makes the UI reload the old cached history, so recent conversation appears to have disappeared despite remaining in the raw rollout. We are not asserting permanent transcript deletion or that authentication caused the duplicate ordinal.

Requested investigation

Please investigate ordinal allocation across the token_count -> thread_settings_applied boundary and provide automatic safe reconciliation, or a supported history repair mechanism, plus an explicit stale-history warning instead of silently showing an old transcript.

We have not applied the manual byte-offset workaround in the opening report, changed affected rollout files, or patched the affected projection checkpoints. An official repair path would be preferable to users guessing which records are safe to skip.

No thread IDs, account information, local paths, prompts, source documents, credentials, raw log archives, or databases are included in this comment.

GINNSOD · 8 hours ago

Confirming this exact defect on a newer Windows hotfix, with an app-wide failure impact.

Environment

  • Windows 11 Pro 25H2, build 26200, x64
  • Microsoft Store package OpenAI.Codex 26.820.10647.0
  • Bundled backend codex-cli 0.150.0-alpha.8
  • ChatGPT sign-in
  • Trigger observed while three gpt-5.6-sol Desktop tasks were resumed/running concurrently at Ultra reasoning effort

The package had updated successfully from 26.820.9563.0 to 26.820.10647.0 about 25 minutes before the failure sequence.

Exact duplicate boundary

The canonical JSONL remained newline-valid and parseable. Its resume boundary was:

ordinal 4921  event_msg/token_count
ordinal 4921  event_msg/thread_settings_applied
ordinal 4922  event_msg/task_started

The persisted projection checkpoint pointed exactly at the second 4921 record and reported:

thread history projection expected ordinal 4922, got 4921

SQLite structural checks passed, and codex doctor reported rollout/state-DB inventory parity as healthy. This confirms the current doctor checks do not detect this semantic duplicate-ordinal/projection-cursor condition.

App-wide impact

This instance escalated beyond stale visible history:

  • the desktop log emitted 60 App server coalesced request queue is full errors in about 0.54 seconds, with pending counts around 129-131;
  • the shared packaged codex.exe app-server exited twice;
  • both exits were 3221225786 / 0xC000013A, signal=null, and classifiedAsExpected=false;
  • the Electron shell remained alive and showed the Windows ChatGPT stopped unexpectedly recovery screen;
  • automatic app-server recovery briefly reconnected, but the same projection error recurred after restart;
  • Windows recorded no matching Application Error, WER report, CrashDump, resource-exhaustion event, GPU reset, WHEA event, or AppX failure.

The affected task is now being kept unloaded to prevent another recovery loop. No rollout, SQLite database, cache, or configuration has been manually altered.

This appears to connect the duplicate-writer/projection defect in this issue and #40109 with the shared app-server failure and queue-saturation families in #35782 and #38385. Ultra concurrency is the observed trigger condition here, but the failing component is the local shared app-server/thread-history path, not remote model inference or system resource exhaustion.

Requested fixes:

  1. serialize/lock concurrent paginated rollout writers before ordinal assignment;
  2. automatically reconcile or rebuild a projection when the canonical rollout contains a duplicate restart-boundary metadata ordinal;
  3. extend codex doctor to verify ordinal monotonicity and raw-versus-projected terminal-state parity;
  4. isolate one thread's projection failure so it cannot terminate the shared app-server and interrupt unrelated tasks.

No thread IDs, task titles, account identifiers, private paths, prompts, project content, raw logs, or databases are included in this report.

vars0 · 7 hours ago

Fresh reproduction on a newer Windows Desktop build, with a higher-impact failure mode than stale history alone.

Environment

  • Windows 11 Home 10.0.26200 (build 26200)
  • Codex Desktop package: 26.825.3734.0
  • Bundled runtime: codex-cli 0.150.0-alpha.12.2
  • Local paginated Desktop thread

Sanitized sequence

  1. At 2026-08-28 04:10:37Z, the rollout appended event_msg/token_count with ordinal 166.
  2. The local app-server transport closed about three seconds later. The immediately preceding application error mentioned a missing custom-tool-call output.
  3. After automatic recovery, at 04:10:53Z, event_msg/thread_settings_applied was appended with ordinal 166 again.
  4. The JSONL remained parseable and had no ordinal gaps, but had exactly that one duplicate.
  5. Every later durable projection attempt reported:

thread history projection ... expected ordinal 167, got 166

  1. The global app-server then repeatedly terminated/restarted with Windows exit code 3221225786 (0xC000013A) — observed again around 04:14:38Z, 04:19:52Z, and 04:27:21Z.

The important additional impact is that this poisoned single thread does not only show stale history: the recurring global app-server restart interrupts active turns in other Desktop tasks as well. One separate task was observed being marked interrupted during recovery.

A read-only scan of nine recent session rollouts found only the active affected rollout with an ordinal defect (one duplicate, no gaps). The machine had ample free memory and no matching Windows Application Error/Hang or resource-exhaustion event, so this does not look like memory pressure or an OS crash.

The app had recently been reset; this thread and the duplicate were created after that reset, so reset/reinstall is not preventive.

Requested containment

  • Allocate the next rollout ordinal atomically across app-server restart/recovery.
  • Reconcile or rebuild a projection when a duplicate metadata boundary is detected.
  • Do not let one thread's projection failure terminate the global app-server or interrupt unrelated tasks.
  • Surface a repair/archive action for the poisoned thread.

No thread IDs, absolute paths, prompts, conversation content, call IDs, credentials, or raw logs are included here. A local observer is retaining privacy-sensitive incident bundles for private follow-up if maintainers request them.

vars0 · 6 hours ago

Follow-up with local mitigation results and a remaining failure mode: the restart loop can be contained, but the originally poisoned thread still cannot display or continue follow-up turns.

Actions performed locally

All changes were preceded by local backups. No canonical rollout JSONL was modified.

  1. Identified two affected paginated rollouts after subsequent restarts:
  • Thread A had duplicate ordinal boundaries at 166 and later 448.
  • Thread B had a duplicate ordinal boundary at 72.
  1. Backed up each affected rollout and created a consistent SQLite online backup.
  2. Applied a narrowly guarded projection-cursor repair only where all of these were true:
  • projection expects N;
  • previous and current rollout records are both N-1;
  • the next record is exactly N;
  • the conditional SQLite update still matches the original byte offset and expected ordinal.
  1. Repairs applied:
  • Thread A: byte offset 1,907,105 -> 1,908,709, expected ordinal remains 167.
  • Thread B: byte offset 1,586,937 -> 1,588,523, expected ordinal remains 73.
  1. SQLite PRAGMA quick_check returned ok.
  2. Built a 1-second observer/guard that records app-server incidents and, on this exact verified duplicate-boundary signature only, backs up the rollout/database before advancing the projection byte offset. It never edits the rollout JSONL.
  3. Tested the full guard in an isolated copy of the rollout and databases:
  • simulated projection at duplicate 448;
  • repaired offset 3,505,250 -> 3,506,854;
  • retained expected ordinal 449;
  • backup receipt created;
  • database quick check remained ok.
  1. Restarted only the Desktop app-server process so it would reload the updated database state.

Outcome

The mitigation partially worked:

  • Thread B recovered: its projection advanced from expected ordinal 73 to 192.
  • The global repeated-restart loop has not recurred since the controlled app-server restart.
  • Thread A remains permanently stale even after a fresh Desktop/app-server process.

Current sanitized Thread A state:

  • canonical rollout size: about 8.0 MB;
  • canonical latest ordinal: 851 and still growing;
  • projection next byte offset: 1,908,709;
  • projection next ordinal: 167;
  • maximum projected ordinal: 164;
  • projected items: 55;
  • projected turns: 2;
  • SQLite quick check: ok.

After restart, thread/resume returns success but reports only the old interrupted turn and turnCount=2. New turn/start requests also return success with no RPC error, and the engine emits reasoning activity for the new turn, but the Desktop history/UI does not advance. To the user, follow-up messages in this thread appear to do nothing.

This demonstrates a second containment gap: advancing past a verified duplicate boundary is sufficient for one thread but not enough to recover every already-wedged projection. The durable rollout can continue to append hundreds of valid ordinals while the materialized history remains frozen without surfacing an error.

Requested product fix

  • Provide an automatic full re-projection fallback when a cursor repair does not advance the materialized history.
  • Detect rollout latest ordinal >> projection ordinal after resume and rebuild instead of returning a successful but stale thread/resume.
  • Reject or visibly fail turn/start if the new turn cannot become visible through the thread projection.
  • Add a supported history repair/reindex command and keep one poisoned thread from affecting the shared app-server.

No thread IDs, local paths, prompts, conversation content, credentials, or raw logs are included. Backups and incident bundles are retained locally for private follow-up.

zshs000 · 4 hours ago

Adding one untouched/read-only data point for the rollout latest ordinal >> projection ordinal case mentioned above.

On another Windows 11 paginated thread using recorded runtime codex-cli 0.149.0-alpha.4.3, I found exactly one non-monotonic boundary in the entire rollout:

20195 event_msg/token_count
20195 event_msg/thread_settings_applied
20196 event_msg/task_started

The persisted projection cursor expected 20196 at exactly the byte offset where the second 20195 began.

The canonical rollout remained valid and continued normally through ordinal 21535, while the history projection remained stuck at that duplicate boundary.

No rollout or SQLite repair has been applied; the original stalled state is still preserved for read-only inspection if maintainers need additional sanitized checkpoint/offset metadata.