Repository navigation
Windows 0.153.4: duplicate thread_settings_applied ordinals after resume permanently stall paginated history #44432
Description
Summary
Windows Codex conversation history freezes at an older turn, although later user and assistant messages remain in the local rollout. Also observed by the user on Android while accessing the same work. Read-only inspection identified two reused rollout ordinals, both on thread_settings_applied events after resuming.
Environment
- Windows, PowerShell
- Running/bundled CLI:
codex-cli 0.153.4 - Local thread with
history_mode=paginated - Approximately 1.56 GB rollout; more than 13,600 records
Exact evidence (no conversation content)
The history projection cursor was stuck at byte 896607608, next ordinal 6076. thread_items contained 2120 entries with max ordinal 6072. The newest-turn reading API returned an old turn while newer durable messages were present.
Record sequence around first failure:
6074 response_item/custom_tool_call_output 2026-09-09T06:49:40.699Z
6075 event_msg/token_count 2026-09-09T06:49:40.709Z
6075 event_msg/thread_settings_applied 2026-09-09T07:09:20.188Z
6076 event_msg/task_started 2026-09-09T07:09:20.204Z
6077 turn_context
The second duplicated ordinal is 13474, again on thread_settings_applied at 2026-09-10T05:46:13.185Z, followed by ordinal 13475 task_started.
A complete JSONL scan parsed every record and found exactly these two sequence violations. Repeated local log message:
failed to project durable rollout: thread-store internal error:
thread history projection ... expected ordinal 6076, got 6075
Scoped diagnostic intervention
After saving the original cursor, the next expected ordinal was temporarily changed from 6076 to 6075 at the same byte offset, for this one thread only. The built-in projector then reached the second duplicate and failed with expected ordinal 13475, got 13474. Projection state and visible items remained at the original boundary, consistent with rollback of the projection batch. No user messages or rollout bytes were edited/deleted. This is diagnostic evidence, not a suggested supported repair.
Expected
Assign a strictly increasing ordinal to settings events when resuming, and recover/rebuild a paginated history safely when duplicate metadata ordinals occur. A later projection failure should not hide a day's intact messages indefinitely.
Related
#43124, #42197, #40630. This report adds the exact event type and adjacent record ordering for two independently observed resume boundaries. The underlying code path responsible for ordinal reuse has not been proven.
No raw transcript, credentials, private project data, personal paths, screenshots, or full logs are included.
Activity
github-actions commentedon Sep 10, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Tanatos8403 commentedon Sep 10, 2026
Follow-up, 2026-09-10: another independently affected conversation
This is recurring across separate local conversations on the same Windows installation, not just the original task in this issue. The user again noticed missing history after an app update/relaunch. The initiating cause is not proven; in this additional case, the duplicated records themselves are dated September 6.
Environment verified today
10.0.29648.OpenAI.Codex 26.903.9818.0.codex-cli 0.153.4(checked the actualcodex.exe, not the separately installed older shell CLI).history_mode=paginated, recorded CLI version0.153.4.Additional case: exact read-only evidence
The newest-turn reading interface returns an old September 6 turn marked
inProgress. Later user messages, assistant final answers andtask_completeevents through September 10 are still in the durable JSONL.The persisted history projection remains:
The first failure boundary is exactly at the saved byte offset. Times below are UTC:
A second duplicate occurs later in the same file:
A full scan at the diagnostic checkpoint parsed 11,433 records successfully and found exactly these two ordinal discontinuities. The file is still being appended to. A fixed backup prefix through a completed September 10 task contains 11,241 records / 182,442,454 bytes, with the completed final answer at
2026-09-10T10:46:04.156Z. That completed work is absent from the indexed view.This is a smaller independent file than the approximately 1.56 GB rollout in the original report. Both have multiple reused
thread_settings_appliedordinals, immediately followingtoken_count.Preservation and impact
For this additional conversation, diagnosis was read-only: no SQLite rows, projection cursors, original JSONL ordinals or messages were changed. We verified a byte-identical local backup of the completed prefix and exported 27 public user/assistant messages to local Markdown to recover working context. This does not restore the application's history view.
The recurring loss of visible context obscures completed work and creates a risk of repeating already completed development/deployment steps. Our earlier report #43600 also documented recurrent stale desktop/mobile history, though the same underlying cause was not established there.
Please investigate ordinal reuse at resume boundaries and provide a supported, non-destructive per-thread replay/rebuild path for already affected conversations, including files with more than one duplicate boundary. The UI should clearly indicate an incomplete history instead of silently presenting an old prefix as the latest state.
No private conversation contents, task identifiers/titles, project names, personal paths, credentials, screenshots or raw transcripts/logs are attached.
Sherlock-haoran commentedon Sep 11, 2026
Additional Windows case verified September 11: eight days of intact conversation hidden behind duplicate ordinal 880
Confirming the same
token_count->thread_settings_appliedordinal reuse with a smaller, 78.6 MB local rollout. This is an independent persisted case; the original producer trigger has not been established.Environment at diagnosis
OpenAI.Codex 26.901.6511.0.26.901.51231.codex-cli 0.153.4.0.150.0-alpha.8; current versions do not prove which runtime created the historical duplicate.history_mode=paginated.User-visible impact and read-only evidence
The desktop displays history only through September 2, despite a September 10 last-updated timestamp. The app's newest-first history interface independently returns only two turns and reports no further pages. The raw rollout still contains later user requests, assistant answers and completed tasks through September 10 at 09:10:17 UTC.
The inspected snapshot contains 5,405 JSONL records / 78,646,124 bytes. Every line parses as JSON. A full ordinal scan found exactly one discontinuity:
response_item/function_call_outputevent_msg/token_countevent_msg/thread_settings_appliedevent_msg/task_startedThe persisted projection state is:
The byte offset points exactly at physical line 882, the reused ordinal. The later projected turn is still stored as
inProgressalthough later completed work exists in the source.The September 11
thread/resumelogs explicitly report (thread identifier redacted):Preservation and requested resolution
A byte-identical local backup was SHA-256 verified. We extracted 19 user messages and 121 assistant messages to a local Markdown file to regain access. This export does not repair the app's history. No original rollout, SQLite row, projection cursor or app setting was modified during diagnosis.
Please provide a supported, non-destructive recovery/replay mechanism for existing affected conversations, prevent duplicate metadata ordinals across resume boundaries, and show an explicit incomplete-history warning rather than an old prefix with a recent last-updated timestamp.
No conversation text, project names, task identifiers, personal paths, credentials, screenshots, raw transcripts or databases are attached. This report establishes the projection failure boundary, not a deterministic clean-install reproduction or the cause of ordinal allocation failure.
silang486 commentedon Sep 13, 2026
Follow-up: producer-side trigger identified
I reproduced the failure boundary in a Windows 0.153.4 paginated rollout and compared it with the current writer implementation.
The durable sequence is:
The likely trigger is the writer recovery path:
RolloutWriterStateincrements its in-memory ordinal only afterwrite_rollout_itemreturns success. If a complete JSONL line has reached disk but the async write/flush reports an error, recovery drops the file handle while retaining the stale allocator. Reopening the file then retries buffered items using the already-used ordinal.That explains why the duplicate is consistently a later
thread_settings_appliedimmediately after atoken_count, and why SQLite stops permanently at that byte boundary while the canonical rollout continues growing.The reader-side projection hardening in current main handles some duplicate/regressed records, but it does not prevent the producer-side reuse seen by installed 0.153.4 builds. I prepared a focused fix that recomputes the ordinal from the durable tail whenever a non-deferred writer is reopened after failure, with a regression test:
The patch is intentionally limited to writer recovery; it does not rewrite or renumber existing rollout data. The exact low-level I/O failure that first puts a writer into recovery mode is still not deterministically reproduced, but the stale-allocator path is now covered and is consistent with the observed ordinal pattern.
GH-LS2023 commentedon Sep 14, 2026
Additional independent evidence from Windows: 10 affected threads and 11 ordinal discontinuities, all matching the resume-boundary pattern reported here.
Environment and scope
26.903.61454.0.153.4; this is not proof of the executable version at every later resume.26.908.4834.0and the running bundled CLI reported0.154.0-alpha.6.2. We have not established whether that build fixes the underlying defect.New correlation: ordinal deficit equals trailing token_count records
Across all 11 inspected discontinuities:
event_msg/thread_settings_applied.event_msg/token_count, the resumed segment reused one ordinal.event_msg/token_countrecords, the resumed segment started two ordinals behind the expected next ordinal.Representative sequences, with timestamps converted to UTC and conversation content omitted:
The remaining eight threads each had one validated discontinuity with the same pattern, including additional two-token_count cases.
This suggests that resumed writer initialization may derive the next ordinal from a history representation that omits trailing token-count events, rather than from the last durable raw ordinal. This is a hypothesis supported by the repeated boundary pattern, not source-level verification.
User-visible effect and projection evidence
Later user and assistant messages remained in the JSONL files but disappeared from paginated history. The two examined projection cursors remained at:
Subsequent logs repeatedly reported:
Restarting did not repair these persisted conflicts. The built-in
migrate-rollouts --thread ... --jsoninspection returnedalready_paginatedfor both threads, despite their stalled projections.Recovery verification (diagnostic evidence, not a supported repair recipe)
With consistent SQLite backups and original rollout copies preserved, an isolated copy was converted through the native migration tool to rebuild continuous ordinals and projections. Record-by-record comparison preserved payloads, allowing ordinal changes and null defaults added by native serialization. The two repaired logs contained 1,527 and 3,995 records. After the validated per-thread repair was applied with file locks released, both projections reached EOF and previously missing messages were readable from the index. Eight other confirmed affected threads were left unchanged.
This repairs the existing data only; it does not establish that the producer bug is fixed or that future resumes cannot reproduce it.
Potential regression coverage: resume paginated rollouts ending with one and multiple token_count events, then assert both strictly increasing persisted ordinals and projection advancement through subsequent user/assistant messages. Recovery for already-paginated malformed histories would also help users whose conversations currently appear truncated.
No raw transcripts, private thread IDs, project names, local user paths, credentials, or full logs are attached.