Data loss: CODEX_HOME runtime directories (incl. sessions/ and archived_sessions/) deleted under a running app on Windows — 417 of 431 threads lost, no error logged

Open 💬 1 comment Opened Aug 7, 2026 by dominikkociecki

Data loss: CODEX_HOME runtime directories (incl. sessions/ and archived_sessions/) deleted under a running app on Windows — 417 of 431 threads lost, no error logged

Summary

On 2026-08-06 at approximately 20:05:35 local time, a selective deletion removed most runtime
directories inside CODEX_HOME (C:\Users\<USER>\.codex) on Windows while Codex Desktop was
running
. sessions/ and archived_sessions/ were among the deleted directories.

The thread index in state_5.sqlite survived intact. The transcripts did not.

Result: 431 thread rows in the database, 14 rollout files on disk, 417 transcripts permanently
lost
, spanning 2026-03-30 to 2026-08-06 — about four months of history.

The application logged no error and no warning at the time of deletion. Sessions that were
mid-turn continued executing tool calls and "writing" to file handles whose directory entries were
already gone. The failure only became visible ~4 hours later, when a thread-list refresh silently
dropped every affected entry from the UI.

This appears to be the same class of failure as #21196 (May 2026, Windows, 90 of 91 threads),
which is still open. This report adds a precise timestamp, the deleted/survived split, and the
elimination of external causes.

---

Environment

| | |
|---|---|
| OS | Windows 11 Enterprise 10.0.26200, NTFS, Entra ID (AzureAD) joined |
| Install | MSIX package OpenAI.Codex_..._x64__2p2nqsd0c76g0 |
| Version at failure | 26.730.8199.0 (app server reported client version 26.730.61639) |
| Previous version | 26.727.6591.0 |
| Update time | 2026-08-06 04:15:41–04:15:42 local (AppXDeploymentServer events 607 / 855 / 472) |
| CODEX_HOME | C:\Users\<USER>\.codex (real directory, not a junction or reparse point) |
| Relevant config | [windows] sandbox = "elevated" |
| CLI versions seen in threads.cli_version | up to 0.147.0-alpha.1.2 |

Note: the update at 04:15 is not the moment of data loss. The app ran normally for roughly
16 hours after it, creating new rollout files the entire time. See timeline.

---

Impact

| Metric | Value |
|---|---|
| Rows in threads (state_5.sqlite) | 431 |
| Existing rollout-*.jsonl files | 14 |
| Missing rollout files | 417 |
| Of those, archived threads (archived_sessions/) | 83 |
| Oldest lost thread | 2026-03-30 04:22:38 |
| Newest lost thread | 2026-08-06 20:02:10 |
| Oldest surviving thread | 2026-08-06 20:05:42 |

The cutoff is exact to the second. Every thread created before 20:05:42 lost its transcript.
Every thread created at or after that second survived. Nothing is missing from after the event —
verified again several hours later, the counts were unchanged (431 / 14 / 417). This was a single
event, not ongoing corruption.

---

Timeline (local time)

| Time | Event | Evidence |
|---|---|---|
| 08-06 04:15:41 | MSIX update 26.727.6591.026.730.8199.0 | AppXDeploymentServer/Operational, events 607, 855, 472 |
| 08-06 04:18:34 | Main Codex process starts (pid:95604) | logs_2.sqlite, first row for that process_uuid |
| 04:18 → 20:02 | App runs normally, creates rollout files continuously | threads created 19:48, 19:53, 20:02 all have rows and are now missing |
| 08-06 20:05:26 | Thread 019f2ec6-… dispatches exec tool call | codex_core::tools::parallel |
| 08-06 ~20:05:35 | Deletion occurs | inferred from directory creation timestamps below |
| 08-06 20:05:36.731 | .sandbox/ recreated; sandbox.2026-08-06.log created, first line written | filesystem + sandbox log |
| 08-06 20:05:41–20:06:01 | computer-use/, cache/, memories/, sessions/, visualizations/, .sandbox-bin/ recreated | directory CreationTime |
| 08-06 20:05:42 | First surviving rollout written | sessions/2026/08/06/rollout-2026-08-06T20-05-42-….jsonl |
| 08-06 20:06:00 | Same thread 019f2ec6-… dispatches another tool call — its rollout file no longer exists | codex_core::tools::parallel |
| 08-06 21:35:01 | First symptom: ERROR codex_rollout::list: state db returned stale rollout path for thread … | logs_2.sqlite |
| 08-07 00:10:50 | Mass symptom: warning storm, WARN codex_rollout::state_db … state db discrepancy during list_threads_db, one per affected thread. Triggered by app_server.client_name="codex_chatgpt_ios_remote" calling list_threads. UI silently drops all affected entries. | logs_2.sqlite |
| 08-07 00:11:14–00:11:34 | Second reset: installation_id, skills/, automations/, vendor_imports/ regenerated; .sandbox/setup_marker.json written with "version": 5; local accounts CodexSandboxOffline / CodexSandboxOnline created | filesystem, Get-LocalUser |

---

What was deleted vs. what survived

Deleted and recreated (directory CreationTime reset to 20:05:36–20:06:01):

.sandbox/            20:05:36
computer-use/        20:05:41
cache/               20:05:42
memories/            20:05:42
sessions/            20:05:43   <-- user data
visualizations/      20:06:01
.sandbox-bin/        20:06:00
models_cache.json    20:05:43
session_index.jsonl  20:05:49
cap_sid              20:05:48
archived_sessions/   never recreated - does not exist   <-- user data

Survived:

state_5.sqlite       CreationTime 2026-03-30
logs_2.sqlite        CreationTime 2026-05-08
memories_1.sqlite    CreationTime 2026-05-30
goals_1.sqlite       CreationTime 2026-05-22
plugins/             CreationTime 2026-05-13  (incl. plugins/cache/ from 2026-05-13)
sqlite/              CreationTime 2026-03-30
.codex/ itself       CreationTime 2026-03-30

This split matters. It was not an indiscriminate wipe, and it was not explained by file
locking: plugins/cache/ was not held open by any process and survived, while sessions/ did not.
The pattern is consistent with a routine that deletes "regenerable runtime state" — with
sessions/ and archived_sessions/ incorrectly classified as regenerable.

---

Why the application did not notice

There is no error or warning in logs_2.sqlite at 20:05, and no restart: the main process ran
continuously from 04:18:34 to 00:10:50.

Thread 019f2ec6-… dispatched tool calls at 20:05:26 and again at 20:06:00. Its rollout file was
already deleted by the second call. No write error surfaced.

The likely mechanism: Rust's std::fs opens files on Windows with FILE_SHARE_DELETE, so another
process can unlink an open rollout file. The writer keeps a valid handle to a now-unlinked file and
continues appending into nothing, without an error. Any data written after the unlink is lost when
the handle closes.

The first stale rollout path error appeared 90 minutes later (21:35:01), and the full picture
only at 00:10:50 — over four hours after the loss, and only because an external client happened to
request the thread list.

---

Causes ruled out

  • Windows Task Scheduler / user scripts. No scheduled task ran between 19:47:12 and 20:58:59.

Verified via Get-ScheduledTaskInfo across all tasks.

  • Antivirus. F-Secure EPP ran an automated task at 19:56:49 but logged zero detections on

2026-08-06, and its quarantine directory has not been written to since 2026-03-02.

  • The MSIX update itself. It completed at 04:15:42, ~16 hours earlier. No AppX deployment event

exists at 20:05. Rollout files created at 19:48, 19:53 and 20:02 — long after the update — are
also gone, which rules out the update as the deleting agent.

  • Application restart / startup cleanup. The process did not restart. It was mid-turn.
  • User action. No shell command in the sandbox log or the surviving transcripts touches

CODEX_HOME.

---

Prime suspect (correlation, not proof)

The Windows sandbox subsystem.

  • config.toml contains [windows] sandbox = "elevated".
  • The sandbox runs commands as dedicated local accounts (CodexSandboxOffline, CodexSandboxOnline)

and manages deny-read ACLs on CODEX_HOME (.sandbox/deny_read_acl_state.json).

  • .sandbox/ and its log file were created at 20:05:36.731 — the earliest artifact in the whole

series, 5–7 seconds before cache/, memories/ and sessions/ reappear.

  • The same machinery reset a second batch of directories at 00:11 the next night, writing

setup_marker.json with "version": 5 and creating the local sandbox accounts.

  • codex-windows-sandbox-setup.exe is present in %LOCALAPPDATA%\OpenAI\Codex\bin.

I want to be explicit: this is sequence and correlation. I cannot name the process that issued the
delete.

What could not be determined

  • No VSS shadow copies exist on the volume (vssadmin list shadows /for=C: → "No items found"),

so there is no pre-event snapshot to compare against or restore from.

  • The NTFS USN journal has already wrapped. The oldest surviving record mentioning any

rollout- file is from 2026-08-07 00:52:01 — over four hours after the deletion. The delete
records are gone.

  • File-carving recovery was attempted (Recuva): 41 recovered rollout-*.jsonl files,

538,570 lines total, 190 parseable JSON lines, 0 valid Codex records. Filenames and sizes
survived; contents had already been overwritten.

Because of this, the exact deleting process cannot be identified retroactively on this machine.
That itself is part of the report: the product produced no evidence of its own most destructive
event.

---

Expected vs. actual

Expected: transcripts in sessions/ and archived_sessions/ are durable user data. Nothing
should delete them without explicit user action, and any process that does should log it.

Actual: they were deleted alongside caches, in bulk, under a running application, with no log
entry, no error at write time, no user prompt, and no recovery path. The UI then quietly removed the
affected conversations from the sidebar instead of surfacing a fault.

---

Suggested fixes

  1. Never place sessions/ or archived_sessions/ inside any bulk-cleanup or reset scope.

Whatever routine treats cache/, .sandbox/, computer-use/ and visualizations/ as
regenerable must not be able to reach transcript directories.

  1. Log every deletion inside CODEX_HOME with path, reason and calling component, at INFO or

above. Today the single most destructive operation the product performs leaves no trace.

  1. Detect write-after-unlink. On Windows, periodically verify that the open rollout handle still

resolves to an existing directory entry (GetFinalPathNameByHandle / FILE_STANDARD_INFO
DeletePending). Fail the turn loudly instead of silently discarding it.

  1. Startup and periodic integrity check: compare threads rows against rollout_path existence.

Report the delta to the user instead of removing entries from the sidebar.

  1. Do not silently drop threads from the UI when the rollout is missing. Show them as broken,

with the title and first user message that are still in the database — those survived here and
were the only thing that made partial reconstruction possible.

  1. Snapshot before destructive maintenance. Before a sandbox re-initialization or version

migration that touches CODEX_HOME, copy sessions/, session_index.jsonl and state_5.sqlite
to a timestamped folder.

  1. Ship a supported backup path for transcripts. There is currently none. Users only discover

this after losing everything.

---

Reproduction

Not reproducible on demand. The event fired once, on the first use of the sandbox after a version
update, and again in reduced form seven hours later during a setup_marker version-5 migration.
Given #21196 (May 2026, Windows, 90 of 91 threads lost, same signature: index intact, files gone),
this is recurring rather than a one-off.

Evidence available on request: state_5.sqlite (index of all 431 threads), logs_2.sqlite
(2026-07-28 onward, ~80k rows), .sandbox/sandbox.2026-08-06.log, directory timestamp listing,
AppX deployment event export.

Related issues

  • #21196 — Data loss: resumed-thread errors due to missing rollout JSONL files (state still has threads, files gone) — same signature, Windows, still open
  • #24178 — Codex Desktop conversations become empty and resume fails with stale Windows path
  • #13713 — Local Codex Desktop sessions disappear from sidebar after restart (Windows App)
  • #16994 — Desktop automations create runs but no rollout materializes

View original on GitHub ↗

1 Comment

cdordanielegaston-art · 7 days ago

Additional Windows reproduction — 1,676 of 1,677 rollout files missing

I am reporting a second Windows case with the same core signature as this issue: the thread database survived, while almost every rollout JSONL disappeared from both active and archived storage.

Environment

  • Date detected: 2026-08-20 (America/Argentina/Buenos_Aires)
  • OS: Windows 11 Pro Education, version/build 10.0.26200, x64
  • Codex Desktop MSIX: 26.818.2441.0
  • Bundled/standalone Codex reported by codex doctor: 0.147.0
  • CODEX_HOME: default real directory under C:\Users\<USER>\.codex (not a junction)

Measured state

codex doctor --json reports:

  • state_5.sqlite integrity: OK
  • total thread rows: 1,677
  • active rows: 791
  • archived rows: 886
  • active rollout files on disk: 1
  • archived rollout files on disk: 0
  • stale DB rows: 1,676
  • malformed filenames: 0
  • duplicate DB paths: 0
  • scan errors: 0
  • model providers: openai=1677

Attempting to resume an affected task produces the same error class:

failed to resolve rollout path C:\Users\<USER>\.codex\sessions\2026\08\12\rollout-...jsonl: file does not exist

The affected thread metadata remains in state_5.sqlite; its JSONL does not exist anywhere under sessions or archived_sessions.

Timeline evidence

  • Windows AppX deployment logs show Codex Desktop updating from 26.814.5167.0 to 26.818.2441.0 between approximately 10:02 and 10:16 local time.
  • C:\Users\<USER>\.codex\sessions\2026 has a creation timestamp of 2026-08-20 10:37:19.
  • A known affected conversation was still usable before this event and had been exported independently on 2026-08-17.
  • The SQLite databases remained intact. The session payload files did not.

The update timing is correlation only; I cannot identify the process that performed the deletion.

Recovery checks already performed

  • No matching rollout copies in archived_sessions
  • No usable copy in Recycle Bin, Windows.old, VSS, package-local data, or a separate user archive
  • Consistent read-only backups of the surviving SQLite databases were created on another drive before further investigation; all passed PRAGMA integrity_check
  • No raw logs, databases, auth files, personal paths, or credentials are being attached publicly

This case appears materially consistent with #37419 and #21196: durable thread metadata survives while rollout payloads disappear in bulk, leaving stale paths and no supported recovery path. The scale here is 1,676 missing payloads out of 1,677 indexed threads.

Please advise whether maintainers want a narrowly redacted diagnostic extract or specific Windows event IDs/timestamps. Raw logs_2.sqlite will not be shared publicly because it can contain sensitive information.