Skip to content

[macOS Desktop] Reboot can switch app-server runtime and wedge paginated history at a duplicate ordinal #40178

Open

Description

@GravityPoet

Environment

  • OS: Darwin 27.0.0 arm64 arm (macOS)
  • Codex Desktop: 26.818.41509 (build 6962)
  • 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 exist
  • no 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

  1. Start a long-running local paginated Desktop thread and let it write multiple turns.
  2. Leave the thread's rollout and state databases intact.
  3. Restart macOS normally.
  4. Launch Codex Desktop and open/continue the same thread.
  5. 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
    ordinal N before reboot and a different thread_settings_applied record at the same ordinal
    N after reboot).
  6. 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_count record at ordinal 3588.
  • After reboot, the official Desktop app-server wrote thread_settings_applied at ordinal 3588
    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

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

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    app-serverIssues involving app server protocol or interfaces
    on Aug 23, 2026
  2. pomazanbohdan commented on Aug 23, 2026

    @pomazanbohdan

    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.

  3. hugepaper commented on Aug 23, 2026

    @hugepaper

    Windows confirmation of the same duplicate-ordinal boundary, observed after an authentication/session rebuild.

    Environment

    User-visible impact

    After the repeated refresh_token_invalidated sign-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:

    • 63 user-created local threads; 0 archived
    • all 63 remain present in the state database, session index, local display catalog, and their rollout files
    • all 63 catalog rows have missing_candidate = 0
    • SQLite integrity checks returned ok
    • no missing rollout file was found for any of the 63 user threads

    There 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:

    • canonical rollout size: 105,667,652 bytes
    • JSONL records: 11,645
    • invalid JSON records: 0
    • last canonical ordinal: 11643
    • duplicate ordinals found: exactly 1
    • ordinal 591 occurs exactly twice, consecutively:
      1. event_msg / token_count, ordinal 591
      2. event_msg / thread_settings_applied, ordinal 591
    • stored projection cursor:
      • next_rollout_byte_offset = 6502760
      • next_rollout_ordinal = 592
    • the record at that byte offset is the second ordinal 591
    • materialized history contains only 183 items and 5 turns, while the canonical rollout continues through ordinal 11643

    The live writer repeatedly reports:

    failed to project durable rollout: thread-store internal error:
    thread history projection expected ordinal 592, got 591
    

    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

    • A GUI-session rebuild, reauthentication, or restart must not append a duplicate paginated ordinal.
    • On a cursor/ordinal mismatch, Desktop should rebuild the derived history projection from the intact canonical rollout.
    • Reauthentication or catalog-host changes should not make intact local conversations disappear from the sidebar.

    No identifiers, credentials, conversation text, filenames, absolute paths, email addresses, request IDs, account IDs, thread IDs, or raw log/database files are included.

  4. hugepaper commented on Aug 23, 2026

    @hugepaper

    Additional read-only follow-up narrows both the likely mechanism and the scope of the Windows instance reported above.

    Exact #35746 fingerprint and handoff timeline

    The first ordinal-591 record is not merely a generic token_count: its rate_limits, nested primary, and credits fields are all populated structured maps (values intentionally omitted). This exactly matches the resume-tail record fingerprint described in #35746.

    2026-08-22 11:32:13.016Z  event_msg/token_count(591)
    2026-08-22 11:47:59.759Z  event_msg/thread_settings_applied(591)
    2026-08-22 11:47:59.768Z  event_msg/task_started(592)
    

    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_count stopped logging, a different app-server process issued thread/resume about 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_invalidated occurred 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:

    • invalid JSON, invalid UTF-8, blank lines, and non-object records: 0
    • 40 legacy-schema rollouts without ordinals
    • 7 ordinal-schema rollouts: 6 normal, 1 affected
    • backward ordinals: 0
    • skipped ordinal values: 0
    • duplicate ordinals: exactly one pair, the 591 boundary above

    The cursor reported above lands at the exact start of the second 591. In a later snapshot ending immediately after ordinal 11,998 (record timestamp 2026-08-23 10:04:10.214Z), the derived projection was behind by the replayed 591 plus 11,407 later ordinal values (592 through 11,998): 11,408 unprojected physical records and 100,709,536 bytes.

    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.

  5. JaredTheHammer commented on Aug 25, 2026

    @JaredTheHammer

    Additional cross-platform evidence from Windows Codex Desktop 26.818.8289.0, bundled app-server 0.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.

  6. wox0008 commented on Aug 25, 2026

    @wox0008

    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

    • macOS 26.5, arm64
    • Codex Desktop 26.818.61809 (build 7019)
    • bundled CLI 0.149.0-alpha.4.3
    • affected history mode: paginated

    Observed sequence

    1. Before the new Desktop process started, the durable rollout ended with a structured event_msg/token_count record at ordinal N. A type-only inspection confirmed populated rate_limits data and a numeric primary.used_percent; all values are omitted.
    2. The new bundled app-server initialized once. About forty seconds later, thread/resume completed for the affected paginated thread.
    3. About one second after that resume, the same rollout received event_msg/thread_settings_applied at ordinal N, followed immediately by event_msg/task_started at N+1.
    4. A local structural scan parsed every JSONL record successfully and found exactly one duplicate ordinal: this N boundary.
    5. The history projector later failed with the sanitized signature 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:

    • the local thread-store serializes per-thread operations with a process-scoped mutex and retains an OS writer lock for the recorder lifetime: live_writer.rs and mod.rs;
    • resume-tail ordinal discovery still uses scan_next::<RolloutLine>(): ordinal.rs;
    • the projector rejects any physical ordinal below its stored 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

    1. Is the tail-decoding interpretation above consistent with the bundled 0.149.0-alpha.4.3 implementation?
    2. Is there a supported doctor or 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?
    3. Until a fixed build is available, what is the safest supported user action after seeing this signature: stop using the affected thread, export diagnostics through in-app feedback, or another documented procedure?

    Suggested regression: a structured token_count(N) tail followed by a cold sequential resume must append at N+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.

  7. dfg5467 commented on Aug 26, 2026

    @dfg5467

    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:

    • ChatGPT/Codex Desktop: 26.820.60940 (build 7119)
    • Bundled app-server: 0.150.0-alpha.8
    • The duplicate-ordinal boundaries were originally written by Desktop 26.818.61809 / app-server 0.149.0-alpha.4.3
    • macOS arm64; paginated local history

    Read-only audit:

    • The initial audit found 5 affected rollouts out of 77 paginated rollouts. Three diagnostic subagent rollouts were created during investigation, so the execution-time inventory became 5 affected out of 80.
    • The affected set is 3 user threads and 2 depth-1 subagent threads.
    • 23 completed turns are durable in JSONL but absent from the SQLite projection: 21 user-thread turns and 2 subagent turns.
    • All affected JSONL records parse, all files end on complete newline-terminated records, and SQLite integrity checks pass.
    • Every affected projection cursor stops exactly at the first resumed record whose ordinal regressed or duplicated the preceding ordinal.
    • Across the five threads, the live writer emitted 1,078 repeated projection warnings with the expected ordinal N, got N-1/N-2 signature.
    • Desktop restart reconstructs the last projected turn as interrupted and serves that stale projection, even though later final answers and task-complete events remain in the raw rollout.

    Current-build behavior:

    • New records written by 26.820 / 0.150 have remained ordinal-contiguous in the observed samples.
    • The current build does not reconcile any of the five pre-existing 0.149 boundaries. Reopening, reading, resuming, reinstalling, and migrate-rollouts do 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:

    1. At startup/read/resume, compare each paginated projection cursor with the canonical rollout record at that byte offset and the rollout EOF.
    2. If an overlap, duplicate ordinal, regressing ordinal, or stale cursor is detected, rebuild that thread's derived thread_items, thread_turns, and projection state transactionally from the durable rollout.
    3. Preserve the old readable projection until the replacement passes integrity and semantic checks.
    4. Expose the same operation as a supported codex doctor --repair-history or equivalent UI action.
    5. Surface a synchronization error instead of silently showing an older conversation.
    6. Add regression coverage for normal macOS reboot, unfinished-turn shutdown, app-server runtime replacement, duplicate 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.

  8. XiaoTianFan commented on Aug 26, 2026

    @XiaoTianFan

    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

    • Windows x64
    • Codex Desktop 26.820.7780.0
    • Current bundled app-server/CLI 0.150.0-alpha.8
    • The affected boundary was written under 0.149.0-alpha.4.1
    • History mode: paginated

    The 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

    • Durable rollout: 234,948,420 bytes and 21,326 newline-delimited JSON records
    • JSON parse failures: 0
    • Ordinal anomalies: exactly one
    • Boundary shape:
      1. event_msg/token_count(N)
      2. event_msg/thread_settings_applied(N)
      3. event_msg/task_started(N+1)
    • All records after that pair are strictly sequential through the end of the file.
    • The stored projection cursor points to the exact beginning of the second N record while expecting N+1.
    • Live materialized history: 19 turns / 2,149 items
    • Canonical history represented by the complete rollout: 78 turns / 7,297 items
    • SQLite integrity check: ok
    • Foreign-key violations: 0
    • The writer logged the same expected ordinal N+1, got N projection 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 ordinal N+1. The durable rollout itself was not edited.

    After starting the current 0.150.0-alpha.8 app-server and resuming the copied thread:

    • projection advanced to the exact rollout EOF;
    • all 78 turns / 7,297 items materialized;
    • the newest completed turn was returned by thread/turns/list;
    • SQLite integrity remained ok;
    • foreign-key violations remained 0.

    The live installation was not modified.

    This specific skip is narrow: thread_settings_applied produces 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.

  9. evolsb commented on Aug 27, 2026

    @evolsb

    Sanitized macOS Remote confirmation and recovery result from a MacBook Pro host controlled through another Mac.

    Environment:

    • Codex Desktop 26.820 generation
    • macOS arm64 host
    • paginated thread history
    • thread was actively continuing in a Schoolwise worktree while the local Desktop view stayed on a spinner or stale first turn

    Exact boundary:

    • canonical JSONL remained parseable and append-only
    • token_count at ordinal N was followed after resume by thread_settings_applied at the same ordinal N
    • projection state expected N+1 at the byte offset where the duplicate thread_settings_applied record began
    • the next physical line was task_started at N+1
    • current OpenAI projection source maps thread_settings_applied to an empty ThreadHistoryChangeSet

    Backup-first recovery:

    • took a SQLite online backup and verified integrity plus foreign keys
    • saved and hashed the immutable rollout prefix through the duplicate record
    • transactionally advanced only next_rollout_byte_offset by the exact duplicate record length while keeping next_rollout_ordinal unchanged at N+1
    • did not edit, delete, or renumber the canonical JSONL

    Result:

    • projection caught up from 1 turn / 83 items to 2 turns / 1,064+ items and reached exact rollout EOF
    • later live appends have remained synchronized
    • app read now returns the current resumed turn instead of the stale pre-resume turn
    • SQLite integrity and foreign-key checks pass
    • no further expected ordinal N+1, got N errors occurred after the repair

    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.

  10. fengguanghuai commented on Sep 3, 2026

    @fengguanghuai

    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

    • macOS 26.5.2, arm64
    • Codex Desktop 26.831.21537 (build 7579)
    • Bundled CLI / app-server: codex-cli 0.152.1
    • Affected rollout: history_mode = paginated

    Sanitized evidence

    • The canonical rollout contained 4,392 newline-valid JSON records and continued through the latest completed turn.
    • There was exactly one ordinal discontinuity:
      1. physical record 1,247: event_msg / token_count, ordinal 1246
      2. physical record 1,248: event_msg / thread_settings_applied, ordinal 1246
      3. physical record 1,249: event_msg / task_started, ordinal 1247
    • The history projection cursor stopped at byte offset 8,898,095, with next_rollout_ordinal = 1247. That offset is the start of the second record using ordinal 1246.
    • The materialized history exposed only 16 turns, while the canonical rollout contained 70 turns, including later completed user and assistant messages.
    • The live writer repeatedly logged:
    failed to project durable rollout: thread-store internal error:
    thread history projection expected ordinal 1247, got 1246
    
    • The warning was observed 360 times over roughly ten hours. Restarting and reopening the app did not repair the projection.
    • codex migrate-rollouts --thread <redacted> --json reported already_paginated with bytes_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:

    1. I preserved the original rollout and SQLite databases before attempting recovery.
    2. In an isolated copy, I corrected only the duplicate top-level ordinal and the subsequent top-level ordinal values. Every other JSON field, every record's byte length, all byte offsets, and the total file size remained unchanged.
    3. The bundled app-server then rebuilt the projection from 16 to all 70 turns, with the latest turn marked completed.
    4. Repeating the same procedure only after fully exiting Desktop restored the actual task. No SQLite rows were manually modified, and the conversation content was unchanged.

    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 doctor repair 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.

  11. yaoziyaoguai commented on Sep 3, 2026

    @yaoziyaoguai

    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

    • macOS 15.5 (24F74)
    • Codex Desktop 26.901.20858 (build 7658)
    • affected session cli_version: 0.151.0-alpha.7.2
    • originator: Codex Desktop
    • history mode: paginated

    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.

    1. An online backup of the history database was created.
    2. The canonical JSONL was left unchanged.
    3. Only this thread next_rollout_byte_offset was advanced from 3,154,803 to 3,155,415, past the duplicate thread_settings_applied metadata record.
    4. next_rollout_ordinal remained 448.
    5. No user message, assistant message, tool result, or task-boundary event was skipped.

    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:

    • guarantee strictly monotonic ordinal assignment across resume and Desktop window/session transitions;
    • make the projector safely reconcile a duplicate projection-neutral metadata record;
    • compare the canonical rollout tail with the projection cursor on startup/open;
    • provide a supported one-click or doctor-style history-index rebuild/repair;
    • show an explicit incomplete-history/projection-stalled warning instead of silently presenting old content as complete;
    • add regression coverage for a resume/new-window boundary that emits token_count(N), thread_settings_applied(N), then the next record at N+1.

    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.

  12. PaulbCatalyst commented on Sep 6, 2026

    @PaulbCatalyst

    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

    • macOS 26.6.2 (25G83), arm64
    • Codex Desktop 26.901.41600, build 7982
    • Bundled codex-cli 0.153.4
    • Paginated local history
    • Desktop plus Codex Remote from an iPhone

    Exact boundary and impact

    Codex created a macOS launchctl submit self-relaunch job during an active turn. The job terminated the active Codex processes. The pre-restart writer had persisted:

    ordinal 26548  event_msg/token_count
    

    After the app reopened, the resumed writer appended:

    ordinal 26548  event_msg/thread_settings_applied
    ordinal 26549  event_msg/task_started
    

    The history projection remained at byte offset 365188871, expected ordinal 26549, and repeatedly rejected the second 26548. The retained error was equivalent to:

    thread history projection expected ordinal 26549, got 26548
    

    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_applied metadata record. The expected ordinal stayed at 26549, and the canonical rollout was not changed. A subsequent native write allowed projection to catch up to exact EOF. Both SQLite databases passed PRAGMA 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

    1. Allocate paginated ordinals atomically across process termination, restart, and resume.
    2. Safely reconcile this exact duplicate projection-neutral metadata boundary.
    3. Compare projection offset and expected ordinal with the canonical rollout on startup and thread open.
    4. Add a supported history-index rebuild or doctor repair.
    5. Warn when visible history is stale instead of silently presenting it as complete.
    6. Isolate a damaged projection so one thread cannot destabilize unrelated Desktop or Remote views.

    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.

  13. nguyenphutrong commented on Sep 6, 2026

    @nguyenphutrong

    I’m seeing a similar issue on macOS. Resuming a local paginated session fails with invalid paginated history lineage ... cycle detected, followed by Conversation interrupted, and part of the conversation history is no longer visible. I have fully quit the app.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions