Skip to content

I recovered a long-running Codex thread with missing history | Chat History is not beeing Displayed #43262

Open

Description

@CanberkGencay

What version of the Codex App are you using (From “About Codex” dialog)?

26.904.11930

What subscription do you have?

Pro

What platform is your computer?

Windows

What issue are you seeing?

I managed to fully recover a Codex conversation on Windows where almost the entire visible history disappeared after restarting the desktop app.

The important part: the conversation data itself was not lost. The rollout JSONL was still complete and continued growing, but the thread-history projection was stuck.

My affected thread:

Started: 2026-08-29
Still actively written on: 2026-09-06
Rollout size: 608,475,078 bytes
Codex CLI stable version: 0.153.4
Windows desktop app showed only the beginning of the conversation
codex resume initially also showed only the beginning
The agent could still continue from the correct project/task state

After recovery:

Projection reached the exact end of the 608 MB rollout
27,857 thread items were materialized
42 turns were restored
The complete conversation became visible again in the Windows desktop app

  1. Verify that the original rollout is still there

I checked the most recently modified rollout files:

Get-ChildItem "$env:USERPROFILE.codex\sessions" -Recurse -Filter "*.jsonl" |
Sort-Object LastWriteTime -Descending |
Select-Object -First 20 FullName, LastWriteTime, Length

My affected rollout was:

CreationTime : 29.08.2026 00:13:15
LastWriteTime : 06.09.2026 19:45:32
Length : 608475078

So although the thread was created on August 29, the same rollout was still being updated on September 6.

I also searched the JSONL for text from recent messages that were no longer visible in the UI, and the messages were still present.

  1. Back up the rollout before doing anything
    Copy-Item $f.FullName "$env:USERPROFILE\Desktop\codex-session-backup.jsonl"

Do not modify the original rollout JSONL.

  1. Run Codex Doctor

I updated the CLI and ran:

npm install -g @openai/codex@latest
codex doctor --all --no-color

With Codex 0.153.4, all databases reported healthy:

state DB integrity ok
log DB integrity ok
goals DB integrity ok
memories DB integrity ok
thread history DB integrity ok

The rollout inventory and database inventory also matched.

So this was not normal SQLite corruption.

  1. Scan the rollout for broken ordinal sequences

I used this PowerShell script:

$prev = $null
$lineNo = 0

Get-Content -LiteralPath $f.FullName -ReadCount 1 | ForEach-Object {
$lineNo++

if ($_ -match '"ordinal"\s*:\s*(\d+)') {
    $ord = [long]$Matches[1]

    if ($null -ne $prev -and $ord -ne ($prev + 1)) {
        [pscustomobject]@{
            Line     = $lineNo
            Previous = $prev
            Current  = $ord
            Delta    = $ord - $prev
        }
    }

    $prev = $ord
}

} | Select-Object -First 30

It found two duplicate ordinals:

Line Previous Current Delta
21965 21963 21963 0
87107 87104 87104 0

The first duplicate was:

ordinal 21963 event_msg token_count
ordinal 21963 event_msg task_started
ordinal 21964 world_state

The second one was:

ordinal 87104 event_msg token_count
ordinal 87104 event_msg thread_settings_applied
ordinal 87105 event_msg thread_settings_applied
5. The thread-history projection also had an initial cursor desync

For my thread, thread_history_1.sqlite contained:

Projection state: (122207, 16)
Thread items: (3, 12)
Thread turns: (1, 1)

However, the rollout records around that byte offset were:

offset 119977 ordinal 14 response_item custom_tool_call
offset 120576 ordinal 15 response_item custom_tool_call_output
offset 121356 ordinal 16 event_msg token_count
offset 122207 ordinal 17 event_msg item_completed

So the byte cursor had already moved past ordinal 16, but next_rollout_ordinal still expected 16.

In other words:

byte cursor -> ordinal 17
expected ordinal -> 16

This caused the projection to fail immediately with:

expected ordinal 16, got 17
6. Back up thread_history_1.sqlite

Before changing anything:

$hist = "$env:USERPROFILE.codex\thread_history_1.sqlite"
$bak = "$env:USERPROFILE\Desktop\thread_history_1-before-repair-$(Get-Date -Format yyyyMMdd-HHmmss).sqlite"

python -c "import sqlite3,sys; s=sqlite3.connect(sys.argv[1]); d=sqlite3.connect(sys.argv[2]); s.backup(d); d.close(); s.close()" "$hist" "$bak"

Important: if restoring an SQLite backup later, do not blindly overwrite the main .sqlite file while old -wal or -shm files are still present.

I did this during testing and temporarily got:

wrong # of entries in index idx_thread_items_user_messages

The backup itself was healthy; the problem was mixing the restored DB with WAL state from the newer database.

  1. Fix the initial cursor desync

With Codex completely closed, I corrected only the expected ordinal.

For my thread:

Before: byte offset 122207, expected ordinal 16
After: byte offset 122207, expected ordinal 17

The byte offset stayed unchanged.

I used a guarded update so it would abort if the database did not contain the exact expected values:

$env:CODEX_THREAD_ID = ""
$env:CODEX_HISTORY_DB = "$env:USERPROFILE.codex\thread_history_1.sqlite"

@'
import os
import sqlite3

db = os.environ["CODEX_HISTORY_DB"]
tid = os.environ["CODEX_THREAD_ID"]

con = sqlite3.connect(db)

try:
before = con.execute("""
SELECT next_rollout_byte_offset, next_rollout_ordinal
FROM thread_history_projection_state
WHERE thread_id = ?
""", (tid,)).fetchone()

print("Before:", before)

# THESE VALUES WERE SPECIFIC TO MY THREAD.
if before != (122207, 16):
    raise RuntimeError(
        "Unexpected projection state; nothing changed: " + repr(before)
    )

with con:
    cur = con.execute("""
        UPDATE thread_history_projection_state
        SET next_rollout_ordinal = 17
        WHERE thread_id = ?
          AND next_rollout_byte_offset = 122207
          AND next_rollout_ordinal = 16
    """, (tid,))

    if cur.rowcount != 1:
        raise RuntimeError("Expected exactly one row to change.")

after = con.execute("""
    SELECT next_rollout_byte_offset, next_rollout_ordinal
    FROM thread_history_projection_state
    WHERE thread_id = ?
""", (tid,)).fetchone()

print("After:", after)
print("Integrity:", con.execute("PRAGMA integrity_check").fetchone())

finally:
con.close()
'@ | python -

Result:

Before: (122207, 16)
After: (122207, 17)
Integrity: ('ok',)

Do NOT copy my numeric values. They were specific to my rollout.

  1. After fixing that, Codex 0.153.4 exposed the next problem

The logs then changed from:

expected=16 got=17

to:

expected=21964 got=21963

Example:

level=WARN
expected=21964
got=21963
target=codex_thread_store::local::live_writer

This matched the first duplicate ordinal in the JSONL exactly:

21963 token_count
21963 task_started
21964 world_state

So stable Codex 0.153.4 was now getting past the initial cursor problem, scanning the rollout, reaching the duplicated ordinal, and aborting the complete history projection there.

  1. Codex 0.154.0-alpha.3 successfully rebuilt the thread

This was what finally recovered the complete history.

I first created another SQLite backup:

$hist = "$env:USERPROFILE.codex\thread_history_1.sqlite"
$bak2 = "$env:USERPROFILE\Desktop\thread_history_1-before-alpha-rebuild-$(Get-Date -Format yyyyMMdd-HHmmss).sqlite"

python -c "import sqlite3,sys; s=sqlite3.connect(sys.argv[1]); d=sqlite3.connect(sys.argv[2]); s.backup(d); d.close(); s.close()" "$hist" "$bak2"

I did NOT replace my global stable installation.

Instead:

npx -y @openai/codex@0.154.0-alpha.3 --version

Output:

codex-cli 0.154.0-alpha.3

Then I opened the affected thread using that version:

npx -y @openai/codex@0.154.0-alpha.3 resume

The missing history immediately started showing up again.

The alpha was able to continue through both duplicated ordinal locations instead of aborting the complete projection.

  1. Verify that the complete rollout was consumed

Afterwards, my projection state was:

Projection state: (608475078, 92314)
Thread items: (27857, 92310)
Thread turns: (42, 92141)
Rollout bytes: 608475078
Bytes remaining: 0

The important part:

Projection byte offset: 608475078
Rollout file size: 608475078
Bytes remaining: 0

So the projection had successfully processed the entire 608 MB rollout.

Before recovery:

Thread items: 3
Thread turns: 1

After recovery:

Thread items: 27857
Thread turns: 42
11. Final result

I closed the CLI and reopened the normal Windows Codex/ChatGPT desktop app.

The full conversation history was back.

The original 608 MB rollout JSONL was never edited.

Root cause in my case

The failure chain was basically:

Long-running Codex thread
|
v
Rollout JSONL keeps growing normally
|
v
Projection cursor desync
expected ordinal 16
byte cursor already points to ordinal 17
|
v
Fix expected ordinal 16 -> 17
|
v
Projection continues scanning
|
v
Duplicate ordinal encountered
21963 -> 21963
|
v
Codex 0.153.4 aborts history projection
|
v
Run thread using 0.154.0-alpha.3
|
v
Duplicate/regressed ordinals no longer block the rebuild
|
v
Projection reaches EOF
|
v
Complete desktop conversation history restored

My rollout actually contained two duplicate ordinal sequences:

21963 token_count
21963 task_started
21964 world_state

and:

87104 token_count
87104 thread_settings_applied
87105 thread_settings_applied

So the data was not gone.

The broken part was the materialized/paginated thread_history projection.

WARNING

Please do not blindly run the SQL/Python update above using my numbers.

Values such as:

122207
16
17
21963
87104

were specific to my thread.

Before modifying anything:

Close all Codex/Desktop processes.
Back up the rollout JSONL.
Back up thread_history_1.sqlite using SQLite's backup API.
Verify the backup with PRAGMA integrity_check.
Inspect your own thread_history_projection_state.
Verify the actual JSONL record located at the stored byte offset.
Only correct the cursor if the mismatch is proven.
Do not modify the original rollout JSONL.

In my case, the only manual modification was correcting the initial projection cursor from ordinal 16 to 17.

I left both duplicate records untouched.

After that, running the thread once with 0.154.0-alpha.3 rebuilt the entire history successfully.

Hopefully this helps anyone else whose long-running Windows Codex thread suddenly appears to lose almost all of its history after restarting the app.

What steps can reproduce the bug?

It happens by itself

What is the expected behavior?

Recovering the Chat History

Additional information

No response

Activity

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

    @aki-0128

    I encountered what appears to be the same history-projection failure after updating the Codex desktop app on Windows (latest version offered on 2026-09-10).

    Observed behavior:

    • A long-running Codex task still appears in the task list, but reopening it shows none of the recent conversation history (effectively only the beginning is materialized).
    • Fully quitting and restarting the desktop app did not restore the history.
    • The original rollout JSONL still exists, is approximately 14 MB with 2,881 records, and continues to receive new records.
    • Recent user and agent activity is present in that rollout, so this is not deletion of the transcript.
    • The app/thread API reports only one in-progress turn and returns only the initial user message, which strongly suggests that the thread-history projection/index stopped while the rollout remained intact.
    • Another older task on the same remote host remains readable with more than 1,000 items, so the failure appears task-specific.

    Safety steps already taken:

    • Backed up the affected rollout JSONL without modifying the original.
    • Did not edit the thread-history SQLite database or its WAL/SHM files.
    • Did not publish the transcript because it contains private project information.

    This case may help confirm that the projection issue still occurs in the desktop build available on 2026-09-10. I can provide sanitized ordinal/cursor diagnostics if needed.

  4. madeinemil-droid commented on Sep 11, 2026

    @madeinemil-droid

    I can confirm a successful recovery of the same duplicate-ordinal history projection failure on Windows.

    Affected thread metadata:

    • history_mode: paginated
    • recorded Codex CLI: 0.151.0-alpha.7.2
    • rollout JSONL was valid with no malformed records
    • SQLite integrity checks returned ok

    Verified stalled boundary:

    • projection offset: 9,620,347
    • expected ordinal: 1848
    • record at that offset: event_msg/thread_settings_applied, ordinal 1847
    • immediately following record: event_msg/task_started, ordinal 1848
    • approximately 7.55 MB of valid rollout data remained unprojected

    Before recovery:

    • projected items: 573
    • projected turns: 25

    I completely closed Codex Desktop and resumed the exact thread using the official stable CLI:

    pnpm dlx @openai/codex@0.154.0 resume

    No JSONL or SQLite rows were manually edited.

    After recovery:

    • the projection reached the exact rollout EOF
    • bytes remaining: 0
    • projected items increased to more than 900
    • projected turns increased to more than 50
    • the missing conversation history became visible again in Codex Desktop

    The recovered history remained visible after gracefully closing and reopening Codex Desktop.

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