Repository navigation
[macOS Desktop] Reboot can switch app-server runtime and wedge paginated history at a duplicate ordinal #40178
Description
Environment
- OS:
Darwin 27.0.0 arm64 arm(macOS) - Codex Desktop:
26.818.41509(build6962) - Bundled CLI:
codex-cli 0.149.0-alpha.4.1 - Local Desktop thread history mode:
paginated
Summary
After a normal macOS restart, Codex Desktop can reopen a paginated thread with an older
conversation snapshot, stop responding, or fail to recover it. The canonical rollout JSONL
still contains the newer turns, but the Desktop history projection stops advancing and the UI
serves stale history.
This is not limited to a single missing file. The observed failure is a restart/login bootstrap
race: the app-server runtime selected before reboot is not guaranteed to be the runtime selected
after reboot. When the second runtime resumes the same paginated rollout, it can write a record
with an ordinal already used by the previous runtime. The projection then waits for the next
ordinal forever.
Observed errors
Depending on which action is attempted, the Desktop UI shows variants of:
failed to resolve rollout path ... file does not existno rollout found for thread id ...invalid paginated history lineage ... missing source rollout恢复对话失败(conversation recovery failed)
In another affected state, the thread remains on “thinking” without producing a response, and
retrying reports that the session is already open in another application.
Reproduction timeline
- Start a long-running local paginated Desktop thread and let it write multiple turns.
- Leave the thread's rollout and state databases intact.
- Restart macOS normally.
- Launch Codex Desktop and open/continue the same thread.
- Observe that the Desktop app-server may be launched from a different runtime than before
reboot. The resumed rollout can contain a duplicate ordinal (for example, a valid record at
ordinalNbefore reboot and a differentthread_settings_appliedrecord at the same ordinal
Nafter reboot). - The projection cursor remains at the earlier boundary (expected
N+1), while the raw rollout
continues to grow. Opening the thread shows older history and follow-up/retry may fail.
The same class of failure is likely when switching accounts or otherwise rebuilding the GUI
session, although the clean-restart path above is the independently verified reproduction.
Evidence from one affected thread
- The raw rollout remained newline-valid and sequential through the latest completed turn after
recovery; no conversation content was deleted. - Before reboot, the patched app-server wrote a valid
token_countrecord at ordinal3588. - After reboot, the official Desktop app-server wrote
thread_settings_appliedat ordinal3588
in the same logical thread. - The SQLite projection then stopped at the duplicate boundary and the UI remained behind the
raw rollout. - Reinstalling or reopening the app did not reconcile the projection automatically.
All identifiers, absolute paths, credentials, and conversation content are intentionally omitted.
Expected behavior
- Desktop should select a deterministic, version-compatible app-server runtime across login,
reboot, and GUI-session reconstruction; a later process must not append duplicate paginated
ordinals to an existing rollout. - On startup and thread open,
thread_history_*should be treated as a rebuildable projection:
detect ordinal/byte-offset mismatches, reconcile it from the canonical rollout, and advance it
to the durable end instead of silently freezing. - If a source rollout truly is missing, recovery should report a precise actionable error and
avoid leaving a ghost/stale thread that appears present but cannot continue. - A follow-up should either be durably persisted and start a response, or return an explicit
dispatch failure; it must not appear successful while leaving the thread unchanged.
Impact
Users see several completed rounds disappear from the visible conversation, cannot continue the
latest turn, and may retry against an old context. This is especially damaging for long-running
tasks because the durable record and the UI disagree without a clear recovery path.
Related reports
- Paginated history drops valid flattened rollout records and reuses ordinals #35746 — paginated history drops valid rollout records and reuses ordinals
- Resume opens a long thread at its first turn: 0.146.1 desynced thread_history projection cursors, and later versions never repair them #38792 — desynchronized projection cursors are never repaired on resume
- [Desktop] Completed thread shows stale pre-crash state after restart while rollout & state DB stay intact — thread_history projection is never rebuilt #40112 — Desktop shows stale pre-crash state after restart while durable history is intact
- Serialize concurrent rollout writers before assigning paginated ordinals #40109 — concurrent rollout writers can assign duplicate paginated ordinals
Please consider a startup reconciliation/doctor path and a regression test that exercises a normal
macOS reboot (or GUI-session rebuild) before and after resuming the same paginated thread.
Activity
github-actions commentedon Aug 23, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
pomazanbohdan commentedon Aug 23, 2026
Cross-OS confirmation: the same duplicate-ordinal boundary appears in Windows history after restart (token_count followed by thread_settings_applied at N). The canonical JSONL remains intact while the paginated projection wedges, so repair needs durable-rollout preservation plus a thread_history cursor parity check. Related: #35746, #40109, and #38792.
hugepaper commentedon Aug 23, 2026
Windows confirmation of the same duplicate-ordinal boundary, observed after an authentication/session rebuild.
Environment
19045, x6426.818.41509history_mode = paginatedUTC+09:00)User-visible impact
After the repeated
refresh_token_invalidatedsign-in loop, quitting and reopening Codex Desktop causes previously visible conversation history to disappear from the UI. During a running process, the affected long thread can continue receiving new turns, but the durable history projection does not advance.Read-only validation: the conversations were not deleted
A read-only inspection found:
missing_candidate = 0okThere is also a catalog/selection inconsistency after reauthentication: the globally selected remote-host value matches 0 of the 2 hosts registered in the local catalog, while 33 legacy global project-thread assignments point to the selected project but all 63 current user-thread/catalog rows have a null
project_id. This may help explain the empty sidebar, but it is reported as an observation rather than a proven cause.Exact duplicate-ordinal evidence from the affected paginated thread
At a read-only snapshot:
105,667,652bytes11,645011643591occurs exactly twice, consecutively:event_msg / token_count, ordinal591event_msg / thread_settings_applied, ordinal591next_rollout_byte_offset = 6502760next_rollout_ordinal = 59259111643The live writer repeatedly reports:
This same error was recorded at least 542 times across 3 distinct Desktop/app-server processes, so reopening the app does not reconcile or repair the projection.
The first projection failure began on 2026-08-22 at 21:10 KST, after the 20:28–20:38 KST authentication loop. That establishes temporal correlation only; it does not prove authentication caused the duplicate ordinal.
Expected behavior
No identifiers, credentials, conversation text, filenames, absolute paths, email addresses, request IDs, account IDs, thread IDs, or raw log/database files are included.
hugepaper commentedon Aug 23, 2026
Additional read-only follow-up narrows both the likely mechanism and the scope of the Windows instance reported above.
Exact
#35746fingerprint and handoff timelineThe first ordinal-
591record is not merely a generictoken_count: itsrate_limits, nestedprimary, andcreditsfields are all populated structured maps (values intentionally omitted). This exactly matches the resume-tail record fingerprint described in #35746.The duplicate appears 15m46.743s after the structured
token_count. Records immediately before and after this boundary increase normally.Process attribution cannot be proven from the JSONL because rollout records do not carry a process UUID. The logs nevertheless show a strong handoff signal: the process active for the first
token_countstopped logging, a different app-server process issuedthread/resumeabout 5m52s before the duplicate, and only the newer process overlaps the second record's time window. This is consistent with a cross-process resume, but it is not proof that two writers appended concurrently.The last authentication-manager
401 refresh_token_invalidatedoccurred about 9m30s before the duplicate. The auth error preceded the observed resume/handoff boundary; the logs do not establish that it caused the handoff or ordinal reuse. The first projection failure surfaced later and therefore did not create the already-present duplicate.Local-inventory negative control
At the initial full-scan snapshot, I parsed all 47 available user-created uncompressed rollout JSONL files, totaling 134,967 physical records:
000591boundary aboveThe cursor reported above lands at the exact start of the second
591. In a later snapshot ending immediately after ordinal11,998(record timestamp2026-08-23 10:04:10.214Z), the derived projection was behind by the replayed591plus 11,407 later ordinal values (592through11,998): 11,408 unprojected physical records and100,709,536bytes.This single duplicated ordinal explains the permanently stale projection for one long paginated thread. It cannot by itself explain why all 63 intact local threads disappeared from the Desktop sidebar after reauthentication. The selected-host/project catalog mismatch reported above remains a separate unresolved sidebar/catalog observation; causality is not established.
No field values, credentials, identifiers, paths, conversation content, repository data, or raw files are included.
JaredTheHammer commentedon Aug 25, 2026
Additional cross-platform evidence from Windows Codex Desktop
26.818.8289.0, bundled app-server0.149.0-alpha.4.3.The same paginated projection failure occurred during app-server reconnect: the cursor expected the next ordinal but read a duplicate of the previous ordinal from the canonical JSONL. I found this in 12 local rollouts. A backup-first repair advanced only projection byte offsets past the duplicate metadata records, preserved all raw rollouts, passed SQLite integrity checks, and restored a clean app-server reconnect.
This confirms the startup reconciliation behavior described here is also needed on Windows, and that a rebuildable projection should recover automatically instead of terminating the app-server with
0xFFFFFFFF.wox0008 commentedon Aug 25, 2026
Additional macOS reproduction on a newer build; sequential resume narrows the likely seam
This is a sanitized corroborating observation for #40178, not a separate failure class.
Environment
26.5, arm6426.818.61809(build7019)0.149.0-alpha.4.3paginatedObserved sequence
event_msg/token_countrecord at ordinalN. A type-only inspection confirmed populatedrate_limitsdata and a numericprimary.used_percent; all values are omitted.thread/resumecompleted for the affected paginated thread.event_msg/thread_settings_appliedat ordinalN, followed immediately byevent_msg/task_startedatN+1.Nboundary.expected ordinal N+1, got N; newer durable records remained beyond that boundary while the visible projection stayed stale.I did not find evidence that proves two writers overlapped in this reproduction. The timing is consistent with a sequential process handoff/resume, so concurrent append alone may not be necessary to trigger the fault.
Source-level hypothesis, not a claim about the installed binary
In current public source at commit
7c6eb0e:scan_next::<RolloutLine>(): ordinal.rs;next_ordinal: thread_history_materialization.rs;This makes the #35746 tail-decoding path the leading source-level hypothesis: if a valid top-level ordinal exists but the full trailing payload is skipped during resume-tail decoding, the resumed recorder can seed from an earlier record and reuse
N. The structured rate-limit fingerprint strengthens that match, but this source inspection still does not prove that the installed Desktop binary executed that exact path.Requested OpenAI guidance
0.149.0-alpha.4.3implementation?doctoror repair path for an already-written different-content ordinal collision that preserves the durable rollout, and should the normal projector fail closed rather than skip either record?Suggested regression: a structured
token_count(N)tail followed by a cold sequential resume must append atN+1; a different-content collision must fail closed without discarding the last readable projection.Related: #35746, #38792, and #40109.
Claim boundary: this is one sanitized corroborating observation plus public-source analysis. It does not prove universal scope, data deletion, the exact installed-binary control flow, or that any proposed fix is already available.
Disclosure: this comment was prepared with Codex assistance at the account owner's request. No raw history, identifiers, local paths, credentials, or conversation content are included.
dfg5467 commentedon Aug 26, 2026
Follow-up: repeated macOS reproduction and a failed self-hosted recovery path
No conversation content, full thread identifiers, absolute local paths, credentials, or account information are included below.
Environment:
Read-only audit:
expected ordinal N, got N-1/N-2signature.Current-build behavior:
migrate-rolloutsdo not advance the frozen cursors.Recovery-path finding:
An agent running inside the Desktop app cannot reliably perform the required offline recovery of the same app. Closing Desktop interrupts the hosting agent and its app-server; attempts to hand the repair to a detached local helper did not obtain a stable offline interval and were stopped without modifying any rollout or projection database. This is an architectural dead end for ordinary users, not a viable support procedure.
The product therefore needs a supported recovery path that does not depend on an agent modifying its own live storage:
thread_items,thread_turns, and projection state transactionally from the durable rollout.codex doctor --repair-historyor equivalent UI action.thread_settings_applied, and subagent rollouts.The local canonical records remain preserved for a private diagnostic channel if maintainers request specific sanitized fields. No public raw transcript or database upload will be made.
XiaoTianFan commentedon Aug 26, 2026
Windows appendix: isolated recovery reaches the complete durable history
This is a sanitized corroborating case for the same failure class, with an isolated recovery validation. No project/repository name, local path, thread ID, title, prompt, response text, credential, account identifier, or raw database/log file is included.
Environment and impact
26.820.7780.00.150.0-alpha.80.149.0-alpha.4.1paginatedThe durable rollout continued receiving valid turns through the current day, while Desktop remained frozen at the history visible around the duplicate boundary. Restarting Desktop did not change the visible cutoff.
Read-only evidence
event_msg/token_count(N)event_msg/thread_settings_applied(N)event_msg/task_started(N+1)Nrecord while expectingN+1.okexpected ordinal N+1, got Nprojection failure 435 times; each later append retried and failed at the unchanged boundary.This confirms that the later history was not deleted. The user-visible truncation is the stale derived projection.
Isolated recovery validation
I made private local copies using a SQLite online backup and a byte-for-byte rollout copy. In the copies only, I conditionally advanced the affected projection byte offset past the duplicate
thread_settings_applied(N)record while retaining the expected next ordinalN+1. The durable rollout itself was not edited.After starting the current
0.150.0-alpha.8app-server and resuming the copied thread:thread/turns/list;ok;The live installation was not modified.
This specific skip is narrow:
thread_settings_appliedproduces no projected turn/item change in the current projection mapping, and the isolated replay confirmed no loss of later materialized history. A generic “delete and rebuild projection rows” repair would still encounter the duplicate ordinal unless rebuild/reconciliation explicitly handles the collision.Product implication
The affected thread is recoverable, but ordinary users need a supported offline/startup repair path. A safe implementation could detect when the cursor lands on a duplicate projection-neutral metadata record, preserve the canonical rollout and old readable projection, rebuild or advance transactionally, validate the replacement, and only then publish it. The UI should also surface projection lag instead of presenting the stale history as complete.
Disclosure: this appendix was prepared and submitted with Codex assistance at the account owner's request.
evolsb commentedon Aug 27, 2026
Sanitized macOS Remote confirmation and recovery result from a MacBook Pro host controlled through another Mac.
Environment:
Exact boundary:
Backup-first recovery:
Result:
This independently confirms the same narrow recovery shape reported in #41079 and reinforces the need for automatic duplicate-boundary reconciliation plus a supported doctor/repair command. No thread IDs, absolute project paths, prompts, conversation content, credentials, or raw logs are included.
fengguanghuai commentedon Sep 3, 2026
Newer macOS build confirmation with recovery validation
I can confirm the same duplicate-ordinal boundary and frozen history projection on a newer macOS Desktop build.
Environment
26.5.2, arm6426.831.21537(build7579)codex-cli 0.152.1history_mode = paginatedSanitized evidence
event_msg / token_count, ordinal1246event_msg / thread_settings_applied, ordinal1246event_msg / task_started, ordinal12478,898,095, withnext_rollout_ordinal = 1247. That offset is the start of the second record using ordinal1246.codex migrate-rollouts --thread <redacted> --jsonreportedalready_paginatedwithbytes_processed: 0, so the built-in migration command did not offer a recovery path.Recovery validation
This is recovery evidence, not a recommendation for users to edit session files manually:
completed.This confirms that the durable conversation was intact and that the single duplicate ordinal was sufficient to keep all later turns out of the materialized history. A supported startup reconciliation or
doctorrepair should ideally detect this exact boundary and rebuild the derived projection without requiring users to touch the canonical rollout.No prompts, responses, thread IDs, account details, credentials, local paths, company information, or raw session/database files are included. This comment was prepared with Codex assistance and is being posted at the account owner's request.
yaoziyaoguai commentedon Sep 3, 2026
New macOS confirmation: current Desktop build, silent truncation, exact recovery
I can confirm the same duplicate-ordinal projection failure on a newer Codex Desktop build. This report is submitted with the affected account owner authorization. Identifiers, local paths, repository details, credentials, and conversation content are intentionally omitted.
Environment
User-visible impact
A long-running development conversation silently appeared to have reverted to a much older state. The UI showed no warning that history materialization had stopped. The user spent substantial time locating a supposedly missing task, re-explaining context, and investigating whether work had been lost. This also caused significant unnecessary token usage.
The user recalls opening the task in a separate Desktop window around the affected period, but the exact writer trigger is not independently proven. There was no actual loss of the canonical rollout.
Exact sanitized evidence
Before repair:
canonical JSONL: approximately 139 MB and more than 21,278 physical records
JSONL remained parseable and contained the later conversation
projection cursor: byte offset 3,154,803, next ordinal 448
materialized UI history: 161 items / 2 turns
visible history stopped on 2026-09-02 while the rollout continued through 2026-09-03
exactly one ordinal anomaly existed at the frozen boundary:
event_msg / token_count ordinal 447
event_msg / thread_settings_applied ordinal 447 [duplicate, starts at byte 3,154,803]
next durable record ordinal 448 [starts at byte 3,155,415]
The projection therefore expected ordinal 448 while repeatedly encountering the second 447 record at its stored byte offset.
Backup-first recovery validation
This is diagnostic recovery evidence, not a recommendation that users edit Codex databases.
The projector immediately resumed and caught up to approximately byte 139,431,702 / ordinal 21,325. Materialized history grew from 161 items / 2 turns to 7,310 items / 33 turns, and the missing conversation reappeared in Desktop. The user confirmed recovery.
This independently proves that the apparent data loss was a stale derived projection caused by one duplicate projection-neutral metadata ordinal.
Requested product action
This failure has a severe productivity and trust impact for long-running work. Please treat it as a data-visibility/recovery defect, not a cosmetic history issue.
Requested safeguards:
The affected user is also requesting an account-level review and restoration of usage consumed while diagnosing and re-establishing context after this product defect. I understand that compensation must be handled through OpenAI Support rather than this public issue, but I am documenting the direct usage impact here for traceability.
PaulbCatalyst commentedon Sep 6, 2026
Additional macOS reproduction on the current Desktop generation, with a verified causal chain from a Codex-created forced restart to a duplicate ordinal and disappearing history.
Environment
codex-cli 0.153.4Exact boundary and impact
Codex created a macOS
launchctl submitself-relaunch job during an active turn. The job terminated the active Codex processes. The pre-restart writer had persisted:After the app reopened, the resumed writer appended:
The history projection remained at byte offset
365188871, expected ordinal26549, and repeatedly rejected the second26548. The retained error was equivalent to:The projector error appeared 488 times across three app-server processes. At diagnosis, the projection was behind the durable rollout by 31,437,658 bytes and 3,620 valid records. The unprojected suffix included 13 completed turns. There were no delete, archive, rollback, truncation, or JSON parse errors. Later work could appear live, then disappear when Desktop or iPhone Remote reloaded the stale projection.
Scope and recovery validation
A full local scan covered 828 rollout files totaling 19.65 GB. This was the only rollout with a duplicate, gap, or backward ordinal. All 318 paginated-thread database records had matching projection state and valid references; no other local transcript had persistent projection lag.
After a verified backup, only the affected projection byte offset was advanced by 2,003 bytes past the duplicate
thread_settings_appliedmetadata record. The expected ordinal stayed at26549, and the canonical rollout was not changed. A subsequent native write allowed projection to catch up to exact EOF. Both SQLite databases passedPRAGMA quick_check, the rollout hash remained unchanged, and later projection writes stayed synchronized.The original duplicate remains in the durable rollout, so this is a local workaround, not a permanent repair. A future rebuild could encounter it again.
Requested fixes
The initiating persistent self-relaunch defect is tracked in #23791. Reports of disappearing messages in other iPhone Remote chats did not correspond to additional damaged local rollouts, so a Remote cache or rendering issue may also need investigation.
No private paths, thread identifiers, account identifiers, transcript content, credentials, raw logs, or databases are included here.
nguyenphutrong commentedon Sep 6, 2026
I’m seeing a similar issue on macOS. Resuming a local paginated session fails with
invalid paginated history lineage ... cycle detected, followed byConversation interrupted, and part of the conversation history is no longer visible. I have fully quit the app.