openai / openai/codex

[macOS Desktop 26.903.71938 / CLI 0.153.4] Recurrent missing history: duplicate rollout ordinals stall projection across two threads

Open
#45,010 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app bug session
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

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

Desktop 26.903.71938 (build 8576), read from the installed bundle's Info.plist, not the About dialog. The bundled executable reports codex-cli 0.153.4.

What subscription do you have?

Not checked for this report; account details are omitted from this public diagnostic.

What platform is your computer?

macOS 26.6.2, Apple Silicon arm64. Local desktop tasks with paginated history. Inspected September 12, 2026.

What issue are you seeing?

Recent conversation history repeatedly appears to disappear. In two independently inspected threads, the canonical rollout contains later messages, but the SQLite history projection stops at a duplicate top-level ordinal. The native history API consequently returns an older prefix.

This establishes history becoming inaccessible, not deletion of the later messages that were verified. Repairing one affected transcript restores its history but does not establish that the initiating writer defect is fixed.

Related: #43742, #43124, #41079. This report adds the newer desktop bundle above, two affected threads, and a recovery verified to preserve every non-ordinal byte. Please consolidate if appropriate.

Sanitized failure boundaries
Observation Thread A Thread B
Adjacent ordinal repeats 1 18 in the inspected complete-line prefix
First duplicate's physical line (1-based) 685 252,989
Expected / actual ordinal 684 / 683 252,988 / 252,987
Stalled byte checkpoint 8,225,687 1,701,044,675
Recovery in this investigation Verified below Read-only inspection; not repaired

Both first boundaries contain the same sequence of distinct records, not byte-identical duplicate messages:

event_msg/token_count              ordinal N
event_msg/thread_settings_applied  ordinal N       <- reused ordinal
event_msg/task_started             ordinal N + 1

For A, N=683; for B, N=252987.

Sanitized warning for A:

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

This recurred on persistence/flush attempts. At the saved checkpoint, the next complete JSON record really had ordinal 683. A's original snapshot contained 1,687 valid JSON records, while the native history read exposed only 8 turns and remained behind later completed turns.

What steps can reproduce the bug?

The initiating ordinal-reuse event is not yet deterministically reproducible from a clean profile. These are the observed steps and diagnostic checks:

  1. Continue an existing local desktop task across multiple turns.
  2. Later conversation content becomes absent through the checked history-reading path, although subsequent user/assistant records and completion events exist in the original rollout.
  3. Use native thread/read and thread/turns/list to compare the latest returned turn with the later durable records.
  4. Inspect that thread's thread_history_projection_state and the complete JSON record at its byte checkpoint.
  5. Observe the repeated ordinal and corresponding expected/got warning.

Token/context-window usage at the initiating event was not established. Restart, compaction, concurrent writers, or a specific user action are not claimed as the proven cause.

What is the expected behavior?
  • Later saved messages remain accessible through history and pagination.
  • Prevent ordinal reuse at thread-settings and writer reopen/resume boundaries.
  • Surface an actionable incomplete-history state when projection fails, rather than silently returning a stale prefix.
  • Provide a supported, non-destructive per-thread integrity/recovery operation for already-paginated histories.
  • Identify the released desktop/runtime build containing the applicable fix and whether existing stalled checkpoints recover automatically.
Additional information
Verified recovery for A

This is diagnostic recovery evidence, not a general instruction to rewrite live transcripts or skip arbitrary records.

After verified local backups and confirmation that the target task was unloaded with no open rollout handles, only its top-level ordinal digits were made contiguous. All 1,687 records were retained. No model turn was started.

Every byte other than those digits had identical SHA-256 checksums before and after. Nested metadata and message contents were unchanged. All bytes before the existing projection checkpoint were unchanged; one corrected ordinal crossing a decimal digit boundary increased total file size by one byte.

The same installed 0.153.4 native App Server then resumed the task and caught up its existing projection, without manual edits to history-table rows:

  • Indexed turns: 8 → 18; indexed items after recovery: 653.
  • Final checkpoint: byte offset 12,120,597, ordinal 1687, exactly the repaired file's end.
  • Native thread/turns/list returned the previously missing completed replies.

This verifies recovery of the inspected history, not prevention of future ordinal reuse. Desktop screenshot verification was unavailable, so API recovery is not presented as visual confirmation.

Stable code versus upstream recovery

The public rust-v0.153.4 materializer returns an error when ordinal is lower than next_ordinal, matching the installed binary's failure.

Merged PR #42369 changes projection handling so later valid history can be processed after invalid/discontinuous records. Please clarify the released desktop build carrying this recovery handling, and address both writer-side ordinal reuse and safe recovery of existing transcripts. The component that first reused these ordinals remains unknown.

Another inspected task had continuous ordinals and populated native summary/full history responses, although the desktop read_thread tool returned items=[]. That separate symptom resembles #43468 and is not counted as a duplicate-ordinal incident here.

Privacy: no raw transcripts, databases, screenshots, task IDs, project names, private paths, credentials, conversation text, or unredacted logs are attached.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/thread-store/src/local/thread_history_materialization.rs, especially the materializer behavior referenced at lines 193-199, and compare it with the native thread/read and thread/turns/list paths. The initiating writer component is not identified and clean reproduction is unavailable. Done requires preventing ordinal reuse, recovering valid later history safely, and clarifying the released build containing PR #42369.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, sqlite
Domain
backend, databases
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.