Skip to content

Windows Desktop: duplicate ordinal hides persisted tail; native projection recovery succeeds but loaded history stays stale #44919

Open

Description

@L1nkus

What version of the Codex App are you using?

Windows installed package: 26.903.9818.0, read from the running executable's package path, not the About dialog. Active backend: codex-cli 0.153.4, verified with the running backend executable's --version.

What subscription do you have?

Not independently verified during recovery. The final persisted turn ended with usage_limit_exceeded.

What platform is your computer?

Windows, x64, OS build 26200; PowerShell. A local Desktop conversation associated with a WSL working directory.

What issue are you seeing?

After a normal reboot, a long-running conversation reopened at an older point. Recent user/assistant exchanges and tool activity were absent from Desktop, although they remained in the canonical rollout JSONL. The original thread has now been recovered without editing either rollout, and I confirmed that its missing tail is visible again.

This is related to #44432, #43124, and #42197. The additional evidence here is a successful isolated native replay, exact preservation checks, and the difference between repaired persisted history and an already-loaded Desktop session. Please consolidate with an existing issue if appropriate.

Read-only diagnosis

The thread uses paginated history with an older base rollout and a continuation segment. Both files parsed through EOF:

  • Base rollout: 166,136,929 bytes, 30,371 records.
  • Continuation: 41,417,003 bytes, 7,189 records; final ordinal 37551 at 2026-09-11T17:16:11.269Z.
  • The continuation contains exactly one non-increasing ordinal boundary:
ordinal  type                                timestamp (UTC)
34088    response_item/custom_tool_call_output 2026-08-29T19:23:08.258Z
34089    event_msg/token_count                 2026-08-29T19:23:08.271Z
34089    event_msg/thread_settings_applied     2026-08-29T19:23:44.638Z
34090    event_msg/task_started                2026-08-29T19:23:44.660Z
34091    turn_context                          2026-08-29T19:23:45.711Z

The continuation's thread_history_projection_state row had:

next_rollout_byte_offset = 17972950
next_rollout_ordinal     = 34090

Byte 17972950 starts the second record numbered 34089. Codex repeatedly logged:

failed to project durable rollout for <original-thread-id>:
thread-store internal error: thread history projection for <continuation-id>
expected ordinal 34090, got 34089

The catalog pointed to the correct rollout and had its current timestamp. SQLite quick_check passed. The base segment's much larger offset was valid for its separate file, not a cursor to reset. Projection failures were logged before the reboot; the reboot exposed stale persisted history rather than being established as the original cause.

What steps can reproduce the bug?

Observed sequence, not a deterministic minimal reproducer:

  1. Continue a long-running, paginated local Desktop conversation across multiple sessions.
  2. A token-count record and a later settings-applied record receive the same ordinal. The cause of that reuse has not been established.
  3. Later turns continue to be written to the rollout, while projection repeatedly fails at the earlier collision.
  4. Reboot and reopen the same conversation: Desktop shows the older projected endpoint.

What is the expected behavior?

Durable messages should remain accessible in the original conversation. Ordinal allocation should avoid reuse, and projection failures should produce an actionable indication rather than silently hiding the tail. Please provide a supported, transcript-preserving recovery path for affected threads, including refreshing already-loaded history state.

Additional information: successful recovery evidence

This was a case-specific diagnostic recovery, not a general SQL workaround recommendation:

  1. Backed up databases, WAL/SHM files, indexes, and both rollouts; also made consistent SQLite snapshots.
  2. In an isolated copy, changed only the continuation's expected ordinal from 34090 to 34089, leaving byte offset 17972950 unchanged. This allowed processing the settings record rather than skipping it.
  3. The installed native Codex backend resumed the isolated copy and replayed to byte 41417003 / next ordinal 37552, exactly EOF. SHA-256 checks confirmed both copied rollouts were unchanged.
  4. Compared native-generated projection rows against live state: 1,157 missing items and 15 missing turns, with all 1,204 existing continuation items and 6 existing turns unchanged.
  5. Installed only the native-generated missing rows and the EOF cursor in one SQLite transaction. Other threads' rows were verified unchanged; integrity checks passed. Both original rollout hashes remained unchanged.
  6. The already-running Desktop backend then returned the restored turn IDs but empty item lists, and the visible UI remained stale. A fresh isolated backend returned all 69 items in the final turn and all 5 items in the preceding completed turn. After a full Desktop restart, I confirmed the missing tail was visible in the original conversation.

No canonical transcript was rewritten, renumbered, truncated, or deleted. No state database was deleted, no replacement conversation was created, and no new user turn was submitted during recovery. Private thread identifiers, transcript content, project paths, credentials, and full logs are intentionally omitted.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on Sep 11, 2026
  2. BiranSama commented on Sep 13, 2026

    @BiranSama

    Adding an independent Windows 0.153.4 occurrence from #45228, which I am closing as a duplicate to consolidate the evidence here.

    • Installed Desktop package: 26.903.8094.0; running backend: codex-cli 0.153.4; Windows x64 build 26100.
    • The affected paginated rollout was 220,557,051 bytes / 12,473 JSON-parseable records, with exactly one non-increasing ordinal boundary.
    • In this case the distinct record reusing the ordinal was thread_goal_updated, rather than thread_settings_applied:
    ordinal 9232  event_msg/token_count
    ordinal 9232  event_msg/thread_goal_updated  <- repeated ordinal
    ordinal 9233  event_msg/task_started
    

    The projection expected ordinal 9233 at byte 160165863, the start of the second ordinal-9232 record. It remained on September 8 history while later completed turns were saved through September 13. codex migrate-rollouts --thread <redacted> --json reported already_paginated and processed 0 bytes.

    Case-specific recovery evidence: after backups, an isolated copy using the same installed backend caught up when its byte cursor was advanced to 160166627 (the start of ordinal 9233), keeping the expected ordinal at 9233, then resumed without starting a model turn. Only the duplicate goal-metadata record was passed; the canonical transcript was unchanged. Projection reached EOF at 220557051 / next ordinal 12472, with 6 → 21 turns and 3017 → 3987 items. The three latest completed turns and their available user/assistant summary messages were readable in the isolated backend.

    After transactionally installing only this task's validated projection rows, the already-running desktop history tool returned the restored turn IDs/timestamps but empty item arrays, despite populated SQLite rows and the successful independent reader. This closely matches the remaining loaded-history symptom reported here. We have not yet verified the UI after a full Desktop restart in our case. SQLite quick_check passed, and the original rollout SHA-256 was unchanged.

    This is diagnostic evidence, not a recommendation to edit live databases. The original cause of ordinal reuse is still unproven; no crash, update, or competing-writer cause is asserted. Closing #45228 consolidates tracking and does not mean the underlying product defect has been fixed.

    No private transcript text, paths, task IDs, credentials, or raw logs are included.

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 appbugSomething isn't workingsessionIssues involving session (thread) management, resuming, forking, naming, archivingwindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions