Skip to content

[0.153.4][Windows] Resume reuses two rollout ordinals after trailing token_count records, freezing desktop history #43142

Open

Description

@rashadrao335566

Summary

After resuming an interrupted local task, Codex Desktop repeatedly shows an older conversation state when refreshed or reopened. Later user messages and the completed assistant response are still present in the durable rollout JSONL, but the paginated history projection no longer advances.

This report adds a two-record ordinal regression on bundled CLI 0.153.4 and a specific suspected deserialization path to the existing duplicate-ordinal reports.

Environment

  • Codex Desktop Windows package: 26.901.6511.0
  • Bundled codex-cli --version: 0.153.4
  • Windows 11 Pro x64, build 10.0.26200
  • Affected rollout: history_mode = paginated, recorded CLI version 0.153.4

Verified on-disk failure boundary

The following are actual top-level ordinals, with conversation contents and identifiers omitted. Times are September 5, 2026, UTC+08:00.

Physical JSONL line Time Record Stored ordinal
365 21:00:26.532 tool result 8288
366 21:00:26.543 event_msg/token_count 8289
367 21:00:33.774 event_msg/token_count 8290
368 21:05:01.561 event_msg/thread_settings_applied 8289 (reused)
369 21:05:01.573 event_msg/task_started 8290 (reused)

The inspected segment contains exactly one backward ordinal transition. All lines are valid JSON. Both trailing token_count records contain a rate-limit field used_percent: 82.0.

The segment's projection checkpoint remains:

next_rollout_byte_offset = 2007813
next_rollout_ordinal = 8291

Byte offset 2007813 points exactly to physical line 368. Every subsequent append encounters:

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

Logs show thread/resume at 21:02:40, then resume_interrupted_task and the first projection error at 21:05:01. The history-reading interface still returns the earlier turn as inProgress; later task_complete and user-message records are present in the JSONL. Continuing the task appends more durable records without updating the rendered history.

Suspected implementation cause in rust-v0.153.4

This is a source-level diagnosis consistent with the on-disk evidence, not an independently compiled Rust reproduction:

  1. ordinal_state_for_rollout scans backward as RolloutLine, silently skips rejected records, and sets the next ordinal from the first successfully deserialized record.
  2. ReverseJsonlScanner::finish_record uses ordinary serde_json::from_slice.
  3. The same version already has decode_rollout_line, with an explicit workaround for floating-point deserialization through flattened envelopes under serde_json/arbitrary_precision. The ordinal scan bypasses that decoder.

If the two trailing rate-limit records are rejected by the ordinary deserializer, the backward scan falls back to ordinal 8288 and resumes at 8289. This predicts the exact two-record regression observed above. There is no evidence establishing concurrent writers as the cause in this case.

Observed reproduction and impact

  1. Continue a long-running local task with paginated history.
  2. Resume an unfinished/interrupted turn whose durable tail contains the two rate-limit records above.
  3. Continue working, then refresh/reopen the task.
  4. The UI repeatedly returns to the old turn, although the newer conversation and completed work remain in the raw transcript.

A fresh deterministic reproduction has not been run. The captured resume boundary and repeated history failure are directly observed. This can cause users to repeat already completed work because the displayed conversation appears to have reverted.

Expected behavior / suggested investigation

  • Recover the next ordinal using the same compatible decoder as normal rollout loading, without silently moving backward past valid durable records.
  • Add regression coverage for resuming a paginated rollout ending in multiple token_count records with floating-point rate-limit values.
  • Surface an actionable history error and provide a supported per-thread recovery path for already affected transcripts.

Related: #42027 and #41657 (reused ordinals after resume), #42794 (floating-point decoding failures). Investigation was read-only; no transcript or database repair was attempted. Raw conversations, credentials, thread identifiers, and personal paths are not attached.

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 6, 2026
  2. argszero commented on Sep 6, 2026

    @argszero

    Thanks for the detailed on-disk evidence — the two-record ordinal regression after trailing token_count records is a precise, well-documented failure boundary. I checked this against current main and the good news is that the suspected cause you identified was already fixed upstream by #42378 ("Route rollout reads through the canonical JSON decoder", merged Sep 2, commit 69cebb5d15).

    What #42378 fixed (exactly your suspected cause)

    Your point #3 was correct in spirit, but on current main the backward ordinal scan is now routed through the canonical decoder rather than the bare deserializer:

    • ordinal_state_for_rollout was changed from scanner.scan_next::<RolloutLine>()? (which deserializes the flattened envelope directly and rejects nested decimals) → scanner.scan_next_rollout_line()?.
    • scan_next_rollout_line (reverse_jsonl_scanner.rs:135-143) now decodes via decode_rollout_line (lib.rs:47-69), which manually removes timestamp/ordinal and decodes the item from the remaining object — avoiding Serde's arbitrary-precision flattened-envelope buffering (the serde_json/arbitrary_precision issue for nested floats like used_percent: 82.0).
    • read_history_metadata also went from serde_json::from_str → parse_rollout_line.
    • Deserialize was removed from RolloutLine so no new reader can bypass the canonical decoder.

    Regression coverage added

    #42378 added a test (codex-rs/rollout/src/recorder_tests.rs, ~71 lines) that "resumes a paginated rollout after a token-count record with a decimal rate-limit value and verifies that ordinal sequencing continues" — precisely your "two trailing token_count records with used_percent: 82.0" scenario.

    Worth verifying

    Because the fix targets the forward ordinal scan and the projection path, there's a separate point worth checking on your end: the on-disk projection checkpoint you cited (next_rollout_ordinal = 8291, pointing at line 368 with a reused ordinal 8289) is the strict thread/revert/materialization error (expected ordinal 8291, got 8289) at thread-store/src/local/thread_history.rs:147. That path is not covered by #42378 and is the same expected ordinal repair-gap I flagged on #43124. If your affected transcript already got its projection state committed one ordinal too far, a rebuild (or a per-thread re-project) would still be needed to recover — the decoder fix prevents new recurrences but does not repair an already-advanced checkpoint.

    Recommendation: re-test with a codex-cli build that includes #42378 (≥ the build containing commit 69cebb5d15). If the regression reproduces on the fixed build, the remaining suspect is the strict projection path expected ordinal / already_paginated repair gap, which is separate from the float-decoding cause. This looks like the same family as #43124 / #43129 — worth linking together.

  3. xufei5620 commented on Sep 6, 2026

    @xufei5620

    Additional sanitized evidence on the same Windows MSIX version (26.901.6511.0) and bundled CLI (0.153.4). The observed first failure has a three-ordinal discrepancy rather than two; a later regression produces a cumulative offset of seven.

    Observed behavior:

    • Sending in the affected long-lived local task makes the desktop UI appear stuck. Backend records show that the new turn was accepted and completed.

    • The parseable source JSONL retains the final answer and completion event, while the derived history API returns an older interrupted turn. The latest turn is absent from thread_turns.

    • The original file is approximately 300 MB / 84,000 records; its projection is approximately 80 MiB / 8,000 records behind. Sizes and counts are rounded for privacy.

    • At the first rejected boundary, three sequential event_msg/token_count records are followed by thread_settings_applied reusing an earlier stored top-level ordinal. Hundreds of errors have this redacted structure:

      failed to project durable rollout for <REDACTED>
      thread history projection for <REDACTED> expected ordinal N, got N-3
      

    I also verified a recovery experiment on an isolated local copy, with no credentials, no external model endpoint, and no turn/start request:

    1. Copy the transcript and take SQLite online backups. Use an isolated application home and workspace.
    2. Control: resume the unmodified copy with excludeTurns: true, then query the latest turn. The projection remains behind and the returned latest turn is the old interrupted one.
    3. In the copy only, correct the two backward ordinal transitions and subsequent ordinals to restore the sequence. This particular file starts at ordinal zero and has no history-base reference; this is not a general recipe for segmented/forked histories.
    4. Verify that every byte other than the top-level ordinal numbers is unchanged, using a digest over the remaining bytes. No prompt, response, timestamp, image data, or tool content is removed.
    5. Resume the corrected copy through the same backend and query the latest turn again.
    6. The existing checkpoint advances to the exact end of the file, and the API returns the actual latest turn as completed, with its final answer and completion metadata present.

    No manual history-table deletion or whole-database rebuild was needed in this experiment. This is a successful offline data-recovery test, not an official supported repair command or a code fix preventing recurrence. It also does not prove that the entire desktop freeze is caused by this fault: no UI CPU profile or isolated UI reproduction was captured.

    A supported per-task consistency check/recovery command would help affected users preserve their history. Upstream prevention of ordinal regressions and supported recovery still need investigation, including regression coverage for tails containing multiple token_count records.

    No subscription, authentication, model choice, usage, account or task identifiers, exact timestamps, project information, machine paths, source transcript, database, screenshot, or original log is included in this comment.

  4. argszero commented on Sep 6, 2026

    @argszero

    Thanks for the additional on-disk evidence — and for the clean offline recovery experiment. Two notes so the thread doesn't read as an unfixed defect:

    Your N−3 discrepancy is the same pre-fix mechanism at k=3. On the old decoder, every trailing event_msg/token_count record whose nested rate_limits carries a decimal float (used_percent: 82.0) fails the backward scan's bare-deserialization step, so the scan steps past all of them to the last cleanly parseable line. With two trailing records the resume lands at N−2 (the original report); with three it lands at N−3 (yours); the cumulative later offset of seven is just a later tail with more such records. Since 0.153.4 predates #42378 (merged Sep 2, 69cebb5d15), this is expected behavior on that build — your control run on the unmodified copy and the successful ordinal-repaired run are both consistent with it.

    One genuine coverage gap remains: the #42378 regression test proves k=1 only. resumed_paginated_rollout_continues_after_decimal_token_count (recorder_tests.rs:1002) writes a single trailing decimal token_count and asserts ordinals [0,1,2]. Your tail has three such records, and the original report had two. Generalizing that test to a parameterized k≥2 trailing-decimal tail (asserting resume lands at the true end and appends cleanly) would lock the k-dependent boundary you and rashadrao335566 both hit — it's a small, self-contained regression test if anyone wants to pick it up.

    Your recovery ask maps to the #43124 repair gap. Your experiment (correct the ordinal sequence in a copy → the checkpoint advances to end-of-file) is exactly the manual form of the repair that has no supported command today: the projection can be transactionally wedged at a boundary (expected ordinal N, got N−k), and migrate-rollouts returns AlreadyPaginated without checking projection consistency, so nothing repairs it. I outlined that gap and two fix directions on #43124 (comment above) — a per-task consistency-check/recovery command would naturally live there.

  5. ashjo42 commented on Sep 7, 2026

    @ashjo42

    Independent Windows validation: a narrow producer-side patch based on rust-v0.153.4 has stopped this recurrence in my setup. After deployment, I have now used Codex continuously for about a day without the previous bug recurring. That duration is my real-use report, not an instrumented 24-hour soak test or a claim about every disabled-composer issue.

    Before this, I had repaired the existing history/index about five times with Cursor. It recovered temporarily, but later resumes broke it again. Fixing the index did not change the writer that was producing new duplicate ordinals.

    Tested environment and change

    In codex-rs/rollout/src/ordinal.rs, ordinal_state_for_rollout no longer reverse-scans directly as RolloutLine. It scans as serde_json::Value and calls the existing decode_rollout_line. A valid persisted top-level u64 ordinal is retained even if an unknown/newer record type cannot be decoded, so that occupied ordinal is not reused. Existing missing-ordinal, overflow, malformed-tail and subagent-boundary handling remain in place.

    The important regression is lexical: valid nested used_percent: 0.0 or 64.0 can be rejected by the old flattened-envelope decode even though the values are mathematically integers. With two such final records, skipping both explains reuse of two ordinals. This is consistent with the canonical-decoder fix in #42378; the additional unknown-record handling is a local defensive change, not a claim that #42378 made that exact change.

    Evidence collected before adoption

    Check Result
    Rollout module regression suite just test -p codex-rollout --cargo-profile release: 125 passed
    Synthetic resume matrix Five tail conditions, two independent engine starts each: 10 passed; continuous new ordinals, completed latest turns, projection at EOF
    Real-history A/B on isolated copies Same roughly 87 MB transcript and already-repaired projection, with two valid decimal tail records injected into the copies only: original 0.153.4 reused two ordinals and stalled projection; patched engine passed two independent starts/resumes, with no additional duplicates and projection at EOF
    Targeted desktop verification After restarting onto the patch, submitted two messages through the real desktop composer and saw both replies; navigated away and reopened the task between sends; all 20 newly appended records had continuous ordinals and projection reached EOF
    Subsequent use About one day of continuous normal use without the previous recurrence, as reported above

    The isolated tests used a local fixed response service, so they are not counted as desktop/network acceptance. The two desktop sends occurred in one desktop process after restart. Existing production transcript bytes were unchanged; this deployment did not manually rewrite the production JSONL or SQLite database.

    Added regression cases in recorder_tests.rs exercise the actual recorder resume/write/flush path:

    • One trailing decimal token_count: ordinals remain [0, 1, 2].
    • Two consecutive trailing decimal token_count records: ordinals remain [0, 1, 2, 3].
    • An unknown record with a valid occupied ordinal: the next write advances past it.

    Deployment method and remaining scope

    Built the matching 0.153.4 CLI in release mode, retained the matching neighboring helper executables, and selected the tested binary using the desktop's existing CODEX_CLI_PATH override. Fully restarted the desktop and verified the running executable matched the tested build. This avoided changing the entire engine/protocol version merely to obtain the producer fix.

    This prevents the reproduced creation of new duplicate ordinals. It does not demonstrate automatic recovery of every already-damaged projection. A supported per-task repair path remains valuable; blindly dropping duplicate records would be unsafe when a duplicated record is a real task_started. Please consider the consecutive-decimal regression case when validating a desktop-compatible release/backport.

    CC @rashadrao335566 @xufei5620 @nos1609 — your reports describe the same trailing-record/ordinal-reuse mechanism or repeated failure after index repair, so I am sharing this follow-up for comparison. Related: #35746.

    One separate request: @tibo-openai, would you consider granting one banked Codex usage-reset credit to me (@ashjo42) as a goodwill reward for the repeated debugging, reproduction and validation effort? The intended recipient is the ChatGPT/Codex account used by this GitHub commenter. If account matching requires verification, please direct me to an official private channel; I have omitted the account email and private identifiers here. I understand this is a request, not an entitlement or an approved reward.

    No raw conversation, database, screenshot, credentials, private task identifiers, project names or personal filesystem paths are attached.

  6. a1249754151-sketch commented on Sep 7, 2026

    @a1249754151-sketch

    Additional verified Windows 0.153.4 evidence: multiple affected tasks and a separate stale-history display problem

    Please consider this a high-impact history-correctness and recoverability issue. Completed work and later user messages can disappear from the displayed history while remaining in the durable transcript. Reopening the same task repeatedly does not repair a stalled projection, and users can be led to repeat work that has already completed.

    This comment adds an independent local boundary audit, an isolated recovery experiment, and observations about the already-loaded desktop client. It reports the shipped build below; it does not claim that the upstream fix referenced in the discussion has failed.

    Environment

    • Windows x64
    • Installed package: OpenAI.Codex 26.901.6511.0
    • Running bundled engine, verified with --version: codex-cli 0.153.4
    • On September 8, 2026 (UTC+08:00), the production Windows Store update manifest still returned buildVersion: 26.901.6511.0.

    Directly observed failure boundary

    One main task had this sequence (September 7, 2026, UTC; task identifiers and contents omitted):

    Time Evidence
    03:35:30.325 Durable event_msg/token_count, ordinal 2884
    03:35:44.357 Desktop log: app-server connection cause=stop_process
    03:35:47.197 Desktop log: Launching app
    03:37:39.033 Resume of the same task started
    03:37:40.095 thread/resume returned successfully
    03:37:45.712 Durable event_msg/thread_settings_applied, ordinal 2884 reused
    03:37:45.744 Durable event_msg/task_started, ordinal 2885

    The prior turn had not completed. These logs establish stop/restart/resume timing; they do not establish whether the earlier stop was a user exit or a crash, or prove a concurrent-writer cause.

    The projection checkpoint was next_rollout_byte_offset=51063423, next_rollout_ordinal=2885. That offset points exactly to the second ordinal-2884 record. The record is 2040 bytes; the next record begins at byte offset 51065463.

    Repeated warning shape:

    codex_thread_store::local::live_writer:
    failed to project durable rollout for <redacted>:
    thread history projection for <redacted> expected ordinal 2885, got 2884
    

    A fixed-prefix snapshot contained 9,028 valid JSON records, no missing top-level ordinals, and exactly one nonconsecutive transition: the repeated 2884. Later conversation and completed work remained present. SQLite quick_check returned ok.

    Scope across local tasks

    After that main task was recovered, a read-only boundary audit of all 732 paginated projection states found seven additional stalled states:

    • Three other named main tasks: thread_settings_applied reused the preceding token_count ordinal.
    • Four subagent tasks: task_started reused the preceding token_count ordinal.

    All seven mismatches remained unchanged on a second read-only check. The other 725 boundaries were at the then-current EOF or had a matching next ordinal; this was a bounded checkpoint audit, not an assertion that all history is valid. Another 1,374 legacy tasks were outside this paginated-checkpoint audit.

    The seven additional tasks were not modified. In particular, we did not treat task_started as disposable metadata.

    Recovery experiment and limits

    Consistent SQLite online backups and a fixed-prefix transcript copy were preserved. On an isolated CODEX_HOME, using the same bundled app-server and without starting a model turn:

    1. The original checkpoint continued returning the old history.
    2. Advancing only the derived projection byte cursor past the verified duplicate settings event, while preserving expected ordinal 2885, allowed native resume to project to the snapshot's EOF.
    3. Indexed turns increased from 28 to 48, and indexed items from 705 to 2,105. All pre-existing turn/item IDs remained. The raw transcript prefix hash was unchanged.

    Only after that isolated validation, a guarded, single-thread compare-and-swap update was applied once to the live projection. The existing writer caught up during normal subsequent persistence. No raw transcript, message, turn, other task, or application binary was edited. Subsequent checks showed continued projection progress and no new ordinal-mismatch warnings for that task.

    This is case-specific recovery evidence, not a recommended general SQL repair recipe, and it does not fix the producer that creates new duplicate ordinals.

    Desktop client observation after projection recovery

    After the database caught up, the history-reading interface returned newer turns with empty item arrays in the already-loaded client. Local source inspection shows that this client can fetch fresh turn metadata while using the conversation's stored itemsBackwardsCursor for item requests. This is consistent with a stale item-snapshot boundary; the in-memory cursor value was not directly inspected.

    After a subsequent app restart, retrieval of older completed turns' contents succeeded. Repeated normal navigation to the already-loaded task had not achieved that refresh.

    Requested follow-up

    • Ship/backport the producer-side ordinal recovery fix into the Windows-distributed engine, with a clear affected/fixed-version statement.
    • Provide a supported recovery path for already affected transcripts and projections, distinguishing metadata from lifecycle or message records.
    • Refresh/invalidate client item-snapshot cursors when projection history catches up or is repaired.
    • Surface an explicit incomplete-history error instead of silently displaying an older snapshot.

    No conversation content, credentials, subscription URLs, task IDs/titles, user paths, raw logs, database files, or screenshots are attached.

  7. a1249754151-sketch commented on Sep 7, 2026

    @a1249754151-sketch

    Following up on my verified bug report and recovery evidence: I would also like to request one Codex usage-reset credit as a goodwill acknowledgment for reporting this serious issue and the repeated troubleshooting and recovery work it required, which consumed additional time and Codex usage.

    This is a request for your consideration, not a claim that compensation has already been approved. If account-specific requests cannot be handled in this issue, please direct me to the appropriate official private support channel so I can reference this report there.

  8. alsalim404 commented on Sep 7, 2026

    @alsalim404

    Additional verified Windows case: displayed history stops advancing, including the conversation about the bug

    Independent confirmation on OpenAI.Codex Windows package 26.901.6511.0, with the
    running bundled engine verified as codex-cli 0.153.4, Windows x64 build
    10.0.26200. Observed September 7, 2026.

    User-visible impact

    The user reports that recent messages and completed work disappear from a
    long-lived local task's displayed conversation. After discussing that problem,
    the user reported that the bug-discussion exchange itself also disappeared.
    The exact UI action triggering disappearance has not been isolated. This is an
    audit of an already affected task, not a clean-session deterministic reproduction.

    Read-only evidence

    • The durable JSONL is still being appended to (approximately 121 MB and 11,500
      records at inspection), with history_mode = paginated.

    • A scan parsed all 11,523 records in that observation without invalid JSON. It
      found exactly one nonconsecutive top-level ordinal transition.

    • A response_item/function_call_output has ordinal 6903, followed by
      event_msg/token_count at 6904. After a time gap, the next
      event_msg/thread_settings_applied reuses ordinal 6904 instead of 6905.

    • The derived thread_history_projection_state remains at
      next_rollout_byte_offset = 61623403, next_rollout_ordinal = 6905.

    • Recent codex_thread_store::local::live_writer warnings repeatedly contain:

      expected ordinal 6905, got 6904
      
    • The history-reading interface returns an older turn as inProgress. A
      read-only query of thread_turns agrees; the maximum indexed item update
      ordinal is 6902, while the durable transcript has advanced beyond 11,500.

    • The source transcript contains today's later user messages and completed
      assistant answers, including the answer discussing the missing-history bug.
      Therefore, the checked messages are not lost from durable storage even though
      the rendered/indexed history is stale.

    This matches the duplicate-ordinal / stalled-projection failure family in this
    issue. We have not independently established why the producer reused the
    ordinal, run a patched build, or established whether restarting the desktop
    would repair this instance. The boundary followed a token-count record, but no
    specific floating-point decoding cause is asserted for this case.

    Requested outcome

    Please provide a Windows-shipped fix preventing ordinal reuse, a supported
    per-task recovery mechanism for already-stalled projections, and a visible
    incomplete-history warning. Silently showing an older conversation can cause
    users to repeat external actions that have already completed.

    No transcript, database, screenshot, message content, task/project identifier,
    personal filesystem path, credentials, or account data is attached. This audit
    did not modify the source transcript, SQLite databases, application binary, or
    application configuration.

  9. phytal commented on Sep 7, 2026

    @phytal

    Confirmed on macOS arm64 with Codex CLI 0.153.4. We independently compiled a focused reproduction of the suspected decoding path, and it produces the ordinal reuse described here.

    Two affected sessions had a final pre-restart event_msg/token_count containing decimal used_percent fields. On resume, the next task_started reused that token-count record's ordinal. /btw then failed with:

    Failed to start side conversation: thread/fork failed during TUI bootstrap:
    thread/fork failed: failed to prepare paginated fork: thread-store internal error:
    thread history projection for <thread> expected ordinal 35929, got 35928 (code -32603)
    

    Focused compiled reproduction

    The reproduction uses the rust-v0.153.4 reverse JSONL scanner, reduced equivalent Serde envelope/event structures, and serde_json with arbitrary_precision enabled. It is a parser/scanner reproduction, not a standalone full-CLI crash reproduction. No SQLite database or profile-sharing wrapper is required for this parser failure.

    Given a parseable record at ordinal 35927 followed by a token_count at 35928 with decimal rate-limit percentages, the output was:

    resume scanner rejected: invalid type: map, expected f64 at line 1 column 911
    resume scanner accepted ordinal Some(35927); next Some(35928)
    fixed scanner next ordinal: 35929
    projection decoder ordinal 35927: accepted
    projection decoder ordinal 35928: accepted
    

    Changing only the decimal percentages to integer JSON values made the original scanner choose 35929 correctly.

    Validated fix direction

    In codex-rs/rollout/src/ordinal.rs, scanning as serde_json::Value and calling the existing crate::decode_rollout_line fixes this reproduction:

    -        match scanner.scan_next::<RolloutLine>()? {
    -            Some(ScanOutcome::Parsed(record)) => break record,
    +        match scanner.scan_next::<serde_json::Value>()? {
    +            Some(ScanOutcome::Parsed(value)) => match crate::decode_rollout_line(value) {
    +                Ok(record) => break record,
    +                Err(_) => continue,
    +            },

    We also added a recorder regression to a local checkout of rust-v0.153.4: append a valid paginated token-count tail at ordinal 5 with used_percent: 7.5, resume the recorder, append an agent message, and assert the new record has ordinal 6. The patched rollout/thread-store test run passed 365 tests with serde_json/arbitrary_precision enabled. That local build also includes separate wrapper-specific locking changes, so this count is the combined suite, not a claim that every test specifically exercises this decoder bug.

    The patched binary successfully performed thread/fork on isolated copies of both affected histories after offline repair of their existing duplicates. The decoding change prevents this reproduced allocation error; it does not repair already duplicated ordinals.

    For transparency, the original incidents occurred through a personal multi-profile launcher. The scanner reproduction isolates the decoding failure from that launcher, shared files, and database behavior. No private conversation contents, account data, or session files are included here.

    Related earlier report: #35746.

  10. 0xDEADBEEFC0DEBABE commented on Sep 8, 2026

    @0xDEADBEEFC0DEBABE

    Additional on-disk evidence from Windows x64 with bundled codex-cli 0.153.4 (September 8, 2026).

    The failure recurred immediately after an offline repair had allowed the history projection to consume the entire durable transcript. This suggests that repairing derived history alone is insufficient while continuing to use the affected writer/decoder.

    Observed sequence (local timezone UTC+10; no prompts or identifiers included):

    • 16:30:30: projection replay completed through all 151,613 existing records; next ordinal was 151613 and byte offset matched the 964,319,929-byte EOF.
    • The final existing record had ordinal 151612 and type event_msg/token_count. Its rate_limits.primary.used_percent was serialized as a decimal (3.0).
    • 16:30:52: after reopening/resuming, event_msg/thread_settings_applied was appended with ordinal 151612 again, followed by thread_goal_updated at 151613 and task_started at 151614.
    • Projection then repeatedly failed with: expected ordinal 151613, got 151612. New raw records continued to append while the history view stayed behind.
    • An earlier duplicate boundary had the same token_count -> thread_settings_applied pattern, with used_percent serialized as 0.0.

    Methodology caveat: the offline repair backed up and renumbered the already-affected transcript and corrected its projection byte cursor before replay. The post-repair tail was contiguous and fully projected; the subsequent duplicate was newly produced on resume. This is not an untouched-transcript reproduction, nor a compiled minimal Rust reproduction.

    Source comparison strongly matches the decimal decoding issue addressed by merged PR #42378: ordinal_state_for_rollout previously used the generic flattened RolloutLine decoder, while the fix routes the reverse scan through the canonical decoder. Its resumed_paginated_rollout_continues_after_decimal_token_count regression test covers the corresponding tail shape. I have not independently run that Rust test or validated an updated Desktop runtime on this machine. No concurrent-writer race has been established in this case.

    Could maintainers confirm which Desktop bundled runtime includes #42378, and the supported recovery path for already-stalled paginated histories? Current main also tolerates duplicate/regressed projection ordinals, but avoiding new duplicates and recovering existing history are separate concerns.

    No raw conversation, thread IDs, credentials, or personal paths are attached.

  11. etraut-openai commented on Sep 8, 2026

    @etraut-openai
    Contributor

    Thanks for the bug report. We understand the underlying problem, and a fix has already been fixed here: #42378. It will be included in the next release.

  12. raulblanko commented on Sep 8, 2026

    @raulblanko

    Additional read-only confirmation on Windows with the same installed package, OpenAI.Codex 26.901.6511.0. The affected task's recorded runtime is 0.153.4 and history_mode is paginated.

    The UI and thread-history API show an older conversation fragment, while later user messages and completed assistant replies remain in the durable JSONL. A missing completed reply from 2026-09-08T16:57:26.474Z was recovered intact (8,511 characters).

    Our confirmed boundary (UTC, physical lines are 1-based):

    • Line 1818, byte offset 8527491: ordinal 1817, event_msg/token_count, 2026-09-06T17:39:24.937Z.
    • Line 1819, byte offset 8528308: ordinal 1817 again, event_msg/thread_settings_applied, 2026-09-06T19:27:43.732Z.

    The corresponding thread_history_projection_state is stuck at:
    next_rollout_byte_offset = 8528308
    next_rollout_ordinal = 1818

    The checkpoint points exactly to the repeated ordinal. The inspected transcript contains one nonconsecutive ordinal transition and continues to receive later records. JSON syntax validation succeeds; validating JSON alone does not detect this sequence problem.

    This confirms the same history-projection failure with a one-record ordinal reuse, rather than the two-record regression in the original report. We have not independently reproduced the writer/decoder trigger or tested a repair. The original transcript and databases have not been modified, and a readable copy of the missing reply was preserved.

    Thanks for identifying the fix in #42378. Please clarify which Windows desktop release includes it and whether there is a supported per-thread recovery/reindex procedure for transcripts that already contain a duplicate ordinal. Preventing recurrence and recovering the existing inaccessible history are both important here.

    Private conversation content, local paths, task identifiers, credentials, and full raw logs are intentionally omitted.


    Prepared and posted by OpenAI Codex (AI assistant), acting with the account owner's authorization through their GitHub account.

  13. ashjo42 commented on Sep 9, 2026

    @ashjo42

    Follow-up to my earlier validation: the desktop composer became unusable again after the reported day of successful use. I now have a calibrated CPU trace of an actual first Send click. This remaining failure must not be treated as proof that the ordinal producer patch was overwritten or that it reproduced the decimal-decoder bug again.

    Environment: Windows desktop package 26.901.6511.0, still selecting an external local 0.153.4 build with the previously described ordinal patch. For transparency, the current build also disables WebSocket transport, so this is not a stock release.

    Observed boundary:

    • After correcting independently verified projection checkpoint errors, a no-op diagnostic sent through the app's built-in task API completed in the affected existing task and its answer appeared in the desktop.
    • Sending through that same task's desktop composer still stalls, including after a full restart and in a new desktop window. The editable composer becomes inert, and no corresponding turn/start is observed.
    • A local-only performance trace, correlated with the actual click, samples handleSubmit → PXr's submit callback → DXr.queueSubmit → onSubmitQueued. Mapping uses the installed bundle, not function-name guessing. This proves the first click entered the local-configuration queue; it does not reveal the exact pending variable.
    • Config, requirements and permission-profile RPCs had returned. Changing permission mode and changing to another supported model both updated task settings successfully, but did not unblock desktop sending. Original settings were restored.

    The installed client aggregates permission-mode loading, Windows sandbox readiness, local workspace materialization and workspace-root loading into this pending condition. The queue remains pending until that condition clears. Its preparation callback refreshes configuration/requirements/permission profiles; it does not by itself establish that all aggregated prerequisites have settled. The workspace path can also remain loading while a prerequisite query has no data.

    This looks potentially related to the pending-configuration analysis in #24984, but equivalent symptoms are not proof of the same cause. The current production performance trace cannot identify the specific stuck state. A supported diagnostic logging the aggregate inputs and query status/fetchStatus at submit would help, followed by a regression covering actual desktop send, completion, reopening and another send. A failed preparation should preserve the draft and restore an actionable composer instead of waiting indefinitely.

    The earlier producer regression results remain scoped to ordinal allocation. They are not proof that every disabled-composer failure is fixed. No private transcript, task identifier, project path, account data, raw trace or screenshot is attached.

    Prepared by OpenAI Codex with the account owner's authorization.

  14. raulblanko commented on Sep 9, 2026

    @raulblanko

    @etraut-openai, following your acknowledgment and reference to #42378, please help escalate this to the Windows Desktop/history owner and identify who is responsible for the remaining recovery work. The issue currently has no assignee.

    This is a follow-up to our independently verified report. We installed a newer Windows Desktop package, but the existing task's usable conversation history is still broken. This is materially preventing normal multi-day work, and we need concrete release and recovery guidance.

    The following was checked again on September 9, 2026, at approximately 09:28-09:32 UTC:

    • Previously installed Windows package: 26.901.6511.0.
    • Currently installed package: OpenAI.Codex 26.903.8094.0, confirmed through Windows package metadata.
    • The affected task uses paginated history. Its persisted task metadata still records cli_version = 0.153.4; that field is not an independent measurement of the updated package's executing binary.
    • After the update, the user still sees the old conversation fragment from Sunday, September 6, although it is now Wednesday, September 9 and substantial work has been completed in the meantime.
    • A fresh read-only database check shows that the task's history projection remains at exactly the previously reported boundary:
    next_rollout_byte_offset = 8528308
    next_rollout_ordinal = 1818
    

    That unchanged checkpoint corresponds to the duplicate ordinal already documented in our earlier investigation:

    Physical JSONL line Timestamp (UTC) Record Stored ordinal
    1818 2026-09-06T17:39:24.937Z event_msg/token_count 1817
    1819 2026-09-06T19:27:43.732Z event_msg/thread_settings_applied 1817 again

    The earlier investigation recovered a missing completed assistant response intact and confirmed later durable records beyond this boundary. Today, the completed repository changes and validation reports are still present, while the GUI presents the obsolete conversation state. We have repeatedly had to reconstruct progress and rewrite results so the account owner can understand where the task actually stands.

    This is an ongoing failure of a core working interface. It consumes working time and agent effort, makes reviewing decisions and completed checks difficult, and creates a serious risk of repeating work or acting on obsolete instructions. The existence of later records on disk does not make that history usable through the application.

    Please distinguish the two outcomes that need to be delivered:

    1. Preventing future incorrect ordinal allocation/history-reading failures.
    2. Restoring access to existing tasks whose transcripts or projections are already affected.

    Our post-update check establishes that the second outcome has not been achieved for this task. We have not run a fresh deterministic reproduction of ordinal reuse on the updated package, and we are not claiming that #42378 was reverted or that its producer regression test failed. We need the team to establish exactly what is included in the released Windows package and what it does for already affected history.

    There is also a new Windows Desktop 26.903.8094 report, #44054, describing recent durable messages remaining inaccessible after restart. Its author has not established the same exact ordinal cause, so this should be triaged as related evidence rather than assumed to be an identical failure.

    Please provide an actionable response to the following:

    1. Ownership and priority: Who owns Windows history recovery, and who will coordinate this issue and related reports? Please assign or route it explicitly and state the current triage status.
    2. Exact release information: Which Windows Desktop package and bundled runtime contain the applicable fix? Is that package actually available to users, and how can its presence be verified? The earlier reference to the "next release" does not answer this after an update has left the existing task broken.
    3. Supported recovery for existing tasks: Should this history recover automatically? If so, what should trigger it, and how is completion verified? If not, please provide an official per-task recovery/reindex procedure or a supported diagnostic/escalation path. It should preserve the original records and explain backup, rollback, and verification requirements.
    4. Visible failure reporting: When the projector cannot advance, the application should expose an actionable history-loading error and recovery status. Silently showing an old conversation as the current state leaves the person using it unable to judge what is missing.
    5. End-to-end acceptance: Please test an already affected paginated task across upgrade, reopening, recent-history pagination, another actual GUI send, completion, and reopening again. Verify both that existing later messages become accessible and that new work remains accessible. Coverage for a fresh ordinal-allocation case alone does not establish recovery of an existing affected task.
    6. Next update: If release or recovery timing is not yet known, please say so explicitly and give a concrete next status-update point. We need enough information to decide how to continue work safely.

    Please keep both Windows delivery and existing-history recovery visibly tracked until they are verified. Installing another GUI version without clear recovery guidance has already failed to restore this task. We appreciate the acknowledgment and code fix, but we now need a named owner, precise release information, and a supported path back to usable history.

    This follow-up does not include private conversation content, task identifiers, personal paths, credentials, or raw databases. The original transcript and history databases have not been edited or renumbered during our investigation.


    Prepared and posted by OpenAI Codex (AI assistant), acting with the account owner's explicit authorization through their GitHub account.

  15. astral303 commented on Sep 9, 2026

    @astral303

    I am pretty sure this is a duplicate of #35746.

    As per @etraut-openai, the bug has been fixed in #42378.

    Edited 9/10/2026: Recovery has been implemented in a followup PR #42369.

  16. PracticalSwan commented on Sep 10, 2026

    @PracticalSwan

    Stable rust-v0.154.0 was released on 2026-09-09T22:35:38Z, and its source appears to close both parts of this failure family.

    Two relevant changes compared with rust-v0.153.4:

    1. codex-rs/rollout/src/ordinal.rs: ordinal_state_for_rollout() now calls scan_next_rollout_line() instead of scan_next::<RolloutLine>(), and read_history_metadata() uses the canonical rollout parser. This is the Route rollout reads through the canonical JSON decoder #42378 decoder fix already discussed above and prevents the trailing decimal token_count record from being skipped when choosing the next ordinal.
    2. codex-rs/thread-store/src/local/thread_history_materialization.rs: the projector now parses each line as serde_json::Value, runs codex_rollout::decode_rollout_line(value), and, importantly, handles ordinal < next_ordinal by recording DuplicateOrRegressedOrdinal, advancing the byte checkpoint, and continuing rather than failing the whole projection with expected ordinal N, got N-1.

    That second behavior is the recovery-side gap called out in the earlier comment: an already-written replayed boundary ordinal no longer has to permanently block the valid suffix behind it.

    I have not claimed an end-to-end recovery on the affected Windows Desktop installation. The installed MSIX here is still 26.903.8094.0 and still bundles 0.153.4; I have not modified its databases or restarted it for a diagnostic. The standalone npm package has 0.154.0 available, but the currently running global app-server is owned by another active integration, so I did not replace it mid-process.

    It would be useful for OpenAI to confirm which Desktop/MSIX build first bundles 0.154.0 (or the equivalent commits) and whether opening an already-affected thread automatically re-enters materialization and advances past the old duplicate boundary without a separate supported recovery action.

  17. astral303 commented on Sep 10, 2026

    @astral303

    @PracticalSwan I can confirm that In 0.154.0 recovery is automatic when you resume the thread, implemented by #42369. The loss is at most one item missing from the desktop view, and usually none. The JSONL is untouched and the model context is unaffected.

    Mechanism: resume flushes the rollout, which runs projection catch-up, and #42369 changed the projector to skip replayed ordinals instead of failing, so the valid suffix is projected. The replayed records are skipped, not recovered. The projector only reads turn lifecycle and item_completed records, and the first records of a turn are task_started and the raw user response_item, so the skipped records usually project to nothing anyway.

  18. PracticalSwan commented on Sep 10, 2026

    @PracticalSwan

    Fresh sanitized Windows reproduction from a different local thread, plus post-update status.

    Environment at reproduction:

    • Windows 11 x64
    • Codex Desktop package before Store update: 26.903.8094.0
    • recorded/bundled app-server: 0.153.4
    • paginated rollout; source JSONL remains valid

    Observed boundary:

    • projection checkpoint: next_rollout_byte_offset=3061551, next_rollout_ordinal=587
    • record ending exactly at that byte offset: ordinal 586, event_msg/token_count, timestamp 2026-09-10T08:42:43.373Z
    • first unprojected record: ordinal 586 again, event_msg/task_started, timestamp 2026-09-10T09:45:41.031Z
    • next records continue 587, 588, ... through 1354
    • file: 1,356 valid JSON records, 0 parse errors, 0 forward gaps, exactly 1 duplicated ordinal, 0 backward transitions
    • durable rollout size: 7,913,127 bytes; projection remained at 3,061,551 bytes
    • derived thread_items stopped at rollout ordinal 581 while later durable work was present

    Desktop logs correlate the second 586 with a successful thread/resume immediately before the new turn. The resumed turn subsequently completed and the UI received live activity/turn-complete events, but the persisted history projection stayed behind the duplicate.

    Post-update finding: Microsoft Store has now updated the same machine to Desktop 26.903.9818.0, but a fresh launch still reports app-server 0.153.4. The new package therefore does not yet include the stable 0.154.0 rollout/materialization changes discussed above.

    Reversible recovery experiment on the already-affected thread

    I backed up thread_history_1.sqlite with SQLite's backup API and left the rollout JSONL byte-for-byte untouched. After verifying that the first unprojected record was the single duplicate ordinal 586 and that all following records were continuous from 587 through 1354, I advanced only next_rollout_byte_offset past that one duplicate record while keeping next_rollout_ordinal=587 unchanged. A non-model Desktop thread open/resume then caused the existing 0.153.4 materializer to consume the remaining valid records.

    Post-recovery state:

    • projection: exact EOF 7913127, next ordinal 1355
    • thread_items: 154 -> 393
    • latest projected turn: completed, end ordinal 1354, end byte offset 7913127
    • Desktop thread/resume, thread/turns/list, and thread/items/list all returned without an ordinal/projection error

    This is a narrowly validated local recovery experiment, not a supported general repair procedure. It works here because the invariant is unusually clean: exactly one duplicate at the projection boundary, then a continuous sequence. It should not be generalized to arbitrary damaged histories without equivalent checks.

    No transcript content, prompts, tool outputs, credentials, private thread identifier, or private paths are included here.

  19. 2667741708 commented on Sep 10, 2026

    @2667741708

    Additional sanitized Windows occurrence: duplicate ordinal in a segmented paginated task; recent messages remain on disk but disappear from the Desktop view.

    I am adding this to the existing issue instead of opening another duplicate.

    Verified environment

    • Current installed Windows package: OpenAI.Codex_26.903.9818.0_x64 (read from package manifest and running executable path).
    • A fresh Desktop launch log on September 10 reports app-server 0.153.4.
    • Windows 11 x64.
    • The affected task uses history_mode: paginated and spans three rollout segments with history_base references. The latest segment's session metadata originally recorded CLI 0.153.1; that is not asserted to be the running writer version at the duplicate boundary.

    Verified durable boundary

    Read-only inspection found these adjacent physical records in the latest segment (UTC, September 8):

    JSONL line Timestamp Record Stored ordinal
    6270 08:24:11.814 response_item/custom_tool_call_output 24724
    6271 08:24:11.829 event_msg/token_count 24725
    6272 08:44:38.674 event_msg/thread_settings_applied 24725 again
    6273 08:44:38.689 event_msg/task_started 24726
    6274 08:44:40.553 response_item/message 24727

    The trailing token_count record contains decimal rate-limit values (used_percent: 0.0). The duplicate is a top-level ordinal, not a number extracted from nested message content.

    The user reports that an ordinary discussion about repairing a connection pool is absent from the page. The original JSONL still contains the user request and the assistant's completed reply on September 10, at 11:16:58 UTC and 12:01:02 UTC respectively, plus the intervening implementation request and progress messages. Across the three segments, an earlier read-only scan parsed approximately 139 MB with zero malformed JSON lines.

    Scope / limitations

    • The duplicate ordinal and retained messages are confirmed. The exact current projection checkpoint has not been read, and we have not captured a matching expected ordinal log for this task. Therefore this is evidence consistent with this issue family, not a claim that we have proven the live projector is blocked at this particular offset.
    • No deterministic fresh-thread reproduction or GUI recovery has been performed.
    • No original transcript, ordinal, SQLite table, cache, or application binary was edited. No application process was killed.
    • Full transcripts, screenshots, private task IDs, machine paths, server addresses, credentials, and project data are intentionally omitted.

    Recovery question

    The rust-v0.154.0 source was independently checked: ordinal_state_for_rollout uses scan_next_rollout_line(), and materialization handles ordinal < next_ordinal by recording DuplicateOrRegressedOrdinal and advancing past the replayed line. However, this currently installed Desktop package still runs app-server 0.153.4.

    Please confirm which Windows Desktop package contains both prevention and existing-history recovery, and the supported reopen/resume procedure for segmented histories with history_base references. A supported per-task diagnostic/repair procedure should preserve original message bytes and expose any skipped records. Updating a standalone CLI should not be confused with updating the app's actual backend.

    Prepared and posted by OpenAI Codex (AI assistant), with the user's explicit authorization.

  20. gfreelove commented on Sep 18, 2026

    @gfreelove

    I can reproduce a related issue on Windows with the VS Code extension.

    Environment:

    • VS Code extension session writer: codex-cli 0.153.4
    • Windows 11 x64
    • Source: VS Code (originator: codex_vscode, thread_source: user)
    • This is a normal user thread, not a subagent thread.

    Observed behavior:
    After an interrupted turn / reconnect / recovery, Codex preserves the same logical
    thread ID but creates another physical rollout JSONL file:

    rollout--.jsonl
    rollout--_.jsonl

    The new segment has the same session_meta.payload.id / session_id and contains
    history_base pointing to the previous rollout segment.

    For one ordinary user thread, I observed 6 physical rollout files sharing the same
    thread ID. Another ordinary user thread had 2 segments after an interrupted turn.

    Impact:
    This is not only a third-party UI concern. Tools that read local Codex sessions can
    mistakenly treat every physical rollout as an independent conversation, resulting in
    duplicate sessions, incomplete transcript views, and unsafe per-file deletion.

    Request:
    Please clarify whether automatic reconnect/recovery is expected to create a new
    rollout segment for the same thread. If so, please provide a stable documented way
    for local integrations to enumerate and merge all segments of one logical thread,
    or expose an option/API to avoid segment creation for transient reconnects.

  21. astral303 commented on Sep 18, 2026

    @astral303

    @gfreelove yours is a different issue than this. Yours sounds like #42269, maybe.

    I'm sorry to say but I would push back on your local integrations to update their logic to follow history_base. OpenAI is constantly making changes to session history, history_base and paginated history modes just a recent example. They are currently working on compressed session rollouts (experimental, disabled by default), and when that ships by default, stale local integrations will stop working completely.

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