Windows Desktop local state is not crash-safe after power loss: pins/projects reset, config regresses, future timestamps

Open 💬 7 comments Opened Jun 8, 2026 by dudantas
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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

Codex Desktop Windows app package:

OpenAI.Codex_26.602.4764.0_x64__2p2nqsd0c76g0
Version: 26.602.4764.0

The app was updated before filing this report.

Additional local CLI present on the same machine:

codex-cli 0.125.0

What subscription do you have?

ChatGPT Pro

What platform is your computer?

Microsoft Windows 11 Pro
Version: 10.0.26200
Build: 26200
Architecture: x64
Filesystem: NTFS

What issue are you seeing?

After power loss / abrupt shutdown, Codex Desktop local state is repeatedly coming back in a partially reset or internally inconsistent state.

The user-visible symptoms are:

  • pinned chats disappear from the sidebar;
  • saved projects/workspaces disappear or collapse to a single workspace;
  • some project views show No chats even though local conversations still exist;
  • the TUI/skills refresh can fail because config.toml regresses to an invalid service_tier = "default" value for this installed version;
  • local metadata can get a far-future timestamp (7026), making an old session look newer than real recent sessions.

This has happened multiple times after power loss. It looks like the local Desktop/profile state under %USERPROFILE%\.codex is not crash-safe across abrupt shutdowns. The underlying conversations are generally still recoverable from local SQLite/session files, but the UI state and indexes become misleading or broken.

Concrete local evidence

The affected local state directory is %USERPROFILE%\.codex.

1. .codex-global-state.json was rewritten to a minimal state

Before repair, the current .codex-global-state.json had effectively collapsed to one workspace:

file: %USERPROFILE%\.codex\.codex-global-state.pre-repair-20260606-070944.json
size: 2,053 bytes
pinned-thread-ids: 1
project-order: 1
electron-saved-workspace-roots: 1
thread-workspace-root-hints: 0
active-workspace-roots: [%USERPROFILE%]

After reconstructing from a known-good backup and state_5.sqlite, the repaired state contained:

file: %USERPROFILE%\.codex\.codex-global-state.backup-20260606-070944.repaired.json
size: 102,112 bytes
pinned-thread-ids: 11
project-order: 27
electron-saved-workspace-roots: 27
thread-workspace-root-hints: 675

Current post-repair state, after reopening the app, remains healthy:

pinned-thread-ids: 13
project-order: 28
electron-saved-workspace-roots: 27
thread-workspace-root-hints: 675
example project-specific hints: 3 for a project that previously showed `No chats`

The repaired JSON is UTF-8 without BOM. The first bytes are:

123,13,10
2. config.toml regressed to service_tier = "default"

The broken config contained this at the top:

model = "gpt-5.5"
model_reasoning_effort = "xhigh"
personality = "pragmatic"
sandbox_mode = "danger-full-access"
approval_policy = "never"
service_tier = "default"

The local error was:

failed to refresh skills: skills/list failed in TUI: skills/list failed: failed to reload config: C:\Users\<USER>\.codex\config.toml:6:16: unknown variant `default`, expected `fast` or `flex`

Restoring a previous fixed backup of config.toml removed the parse error. The current restored file no longer contains service_tier = "default".

3. A local thread and version cache jumped to year 7026

Before repair, one local thread had:

id: 911d47ec-a3a4-7503-b8ae-3f47cecabbd4
cwd: <redacted project path>
updated_utc: 7026-02-04 18:32:49
updated_ms: 159554946769000
rollout_path: %USERPROFILE%\.codex\sessions\7026\02\04\rollout-7026-02-04T15-32-49-911d47ec-a3a4-7503-b8ae-3f47cecabbd4.jsonl

version.json also had a last_checked_at timestamp in 7026:

{
  "latest_version": "0.96.0",
  "last_checked_at": "7026-02-04T18:32:48.404538600Z",
  "dismissed_version": null
}

The 7026 session file contained only 4 metadata/instruction lines, not meaningful conversation content. After backing up the database and file, I moved it to the matching 2026 path and updated the SQLite row to a 2026 timestamp.

Post-repair validation:

future files under %USERPROFILE%\.codex: 0
future threads in state_5.sqlite: 0
4. Local conversation data was still present

The state database still contained many threads:

state_5.sqlite total threads: 791
active threads: 714

This looks like a local state/index/UI consistency problem rather than complete data deletion.

What steps can reproduce the bug?

This is tied to abrupt shutdown/power loss rather than a deterministic in-app action, but the observed sequence is:

  1. Use Codex Desktop on Windows with multiple saved workspaces/projects, pinned chats, and many local conversations.
  2. Leave Codex Desktop open with app-server/background processes active.
  3. Machine loses power or is abruptly shut down.
  4. Restart Windows and open Codex Desktop.
  5. Observe that the sidebar has lost pins and saved projects, or project views show No chats.
  6. In some cases, launch TUI/CLI or trigger skills refresh and observe config parsing failure from service_tier = "default".
  7. Inspect %USERPROFILE%\.codex and compare:
  • .codex-global-state.json
  • state_5.sqlite
  • session_index.jsonl
  • sessions/**/rollout-*.jsonl
  • version.json

The conversations remain mostly recoverable locally, but the UI state and metadata can be corrupted or reset.

What is the expected behavior?

Codex Desktop should make local state persistence crash-safe across abrupt shutdowns.

Specifically:

  • .codex-global-state.json should not be replaced by a minimal state after a crash if recoverable state exists.
  • Writes to local JSON state should be atomic, for example write temp file, fsync, then rename.
  • config.toml should not regress to a value that the installed parser rejects.
  • Timestamps should be validated or clamped; a local session/version cache should not jump to year 7026.
  • The app should detect drift between .codex-global-state.json, state_5.sqlite, session_index.jsonl, and existing rollout files.
  • If project state is incomplete, Codex should expose a supported local repair/reindex command rather than making users inspect and patch SQLite/JSON manually.
  • Project views should not display No chats when matching active local threads exist in state_5.sqlite and rollout files exist on disk.

Actual behavior

After power loss, Codex Desktop can reopen with:

  • pins reduced from 11+ to 1;
  • saved projects reduced from dozens to 1;
  • workspace hints removed;
  • project chat views empty despite active rows in state_5.sqlite;
  • config.toml containing service_tier = "default", which this install rejects;
  • local metadata containing future year 7026.

Workaround used locally

With Codex Desktop closed:

  1. Back up the broken files/databases.
  2. Restore a known-good config.toml without service_tier = "default".
  3. Rebuild .codex-global-state.json from a known-good backup and active rows in state_5.sqlite.
  4. Preserve and restore:
  • pinned-thread-ids
  • project-order
  • electron-saved-workspace-roots
  • active-workspace-roots
  • thread-workspace-root-hints
  1. Write JSON as UTF-8 without BOM.
  2. Move the sessions\7026\... rollout to the equivalent sessions\2026\... path and update the corresponding SQLite row.
  3. Restart Codex Desktop.

After that, pins/projects/project hints were visible again.

Related issues

This overlaps with several existing local state/sidebar/path reports, but I did not find an exact duplicate for the power-loss/crash-safety combination:

  • #17540: Windows app older local threads disappear from sidebar/search while still present on disk.
  • #24178: conversations become empty and resume fails with C:\... vs \\?\C:\... stale path.
  • #25500: project sidebar shows No chats for projects with older non-archived conversations.
  • #22452: local thread hidden/stale when state_5.sqlite and session_index.jsonl drift.
  • #24425: corrupted session JSON/history after crash; maintainer asked about power loss in discussion.

The distinct parts here are:

  • reproducible trigger is power loss / abrupt shutdown;
  • .codex-global-state.json collapses to a minimal state;
  • config.toml regresses to an invalid service_tier = "default" for this version;
  • a local thread and version cache jumped to year 7026;
  • the same local profile needed coordinated repair across global state JSON, config TOML, SQLite, session index, and session paths.

Additional information

No raw logs_2.sqlite, auth.json, full config.toml, or rollout content is attached publicly because those files may contain private prompts, local project names, tokens, URLs, or account data.

I can provide redacted diagnostics or specific SQL/query output if maintainers say which fields are useful and safe to share.

View original on GitHub ↗

7 Comments

github-actions[bot] contributor · 1 month ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #26421

Powered by Codex Action

dudantas · 1 month ago
Potential duplicates detected. Please review them and close your issue if it is a duplicate. * Desktop: config.toml zero-filled to NUL bytes after ungraceful shutdown — non-atomic write on Windows loses entire file content #26421 _Powered by Codex Action_

I agree this is related to #26421, especially the non-atomic persistence / power-loss angle.

I do not think this is an exact duplicate, though. #26421 focuses on config.toml becoming zero-filled with NUL bytes after an ungraceful shutdown. In this case, config.toml was still readable but regressed to service_tier = "default", while .codex-global-state.json was rewritten to a minimal state and lost pins/projects/workspace hints. The same incident also produced a future-year 7026 timestamp in version.json, a session path, and state_5.sqlite.

So the shared root cause may be crash-unsafe local persistence, but the affected state is broader than config.toml: .codex-global-state.json, session metadata, SQLite timestamps, and project/sidebar recovery are involved too.

dudantas · 1 month ago

Additional update: repeated sidebar loss after recovery + destructive Windows hang dialog

I have continued investigating this locally after the original report. The behavior still looks broader than a single config.toml corruption case.

Installed version still affected

Current installed Windows package on the affected machine:

OpenAI.Codex 26.602.4764.0
PackageFullName: OpenAI.Codex_26.602.4764.0_x64__2p2nqsd0c76g0

Chats can still exist locally while disappearing from the UI

After repairing .codex-global-state.json and recovering old projects/pins, I was able to make old project chats visible again. However, some old project chats can disappear from the sidebar again later.

The important detail is that this does not appear to be complete conversation deletion. Local rows and rollout/session files still exist. The problem appears to be that the Desktop sidebar/project list does not hydrate all local conversations from durable storage. It seems to depend on a combination of:

  • .codex-global-state.json
  • project-order
  • electron-saved-workspace-roots
  • thread-workspace-root-hints
  • pinned-thread-ids
  • recent thread pagination / in-memory hydration
  • state_5.sqlite thread metadata

A temporary workaround was to add missing thread ids to pinned-thread-ids. That forced the Desktop app to hydrate them. After unpinning, those chats moved back under their correct projects based on their workspace metadata. This strongly suggests pinning is acting as a hydration trigger, not as the real source of project membership.

Local SQLite evidence

The affected profile currently has many active local threads whose thread_source is still NULL:

active threads: 719
active threads with thread_source IS NULL: 463
active threads with thread_source = 'user': 256

Several older projects have only or mostly thread_source IS NULL active rows. These are the same kinds of projects that are more likely to show as empty or incomplete in the Desktop sidebar even though matching conversations exist in state_5.sqlite and rollout files.

This may be a migration/indexing issue where older Desktop-created local conversations are still present but no longer pass the current sidebar/recent-thread filters unless they are pinned or otherwise explicitly hydrated.

Additional Windows-specific destructive failure mode

There is another Windows-specific way the crash/hang becomes destructive.

When Codex Desktop freezes while I am typing in the composer, Windows shows the standard Codex is not responding dialog. The focused/default button is End Process. If I press Enter at that exact moment intending to submit my prompt, Windows terminates Codex instead.

Impact:

  • composer draft can be lost
  • pasted/uploading attachments can be lost
  • running threads can be interrupted
  • local state corruption/recovery problems become more likely after forced termination

This is worse than a normal app hang because the default focused Windows action can terminate the app accidentally during normal typing. I have a screenshot of this state, but the raw screenshot contains private workspace paths and prompt content, so I am not attaching the unredacted image publicly.

Relation to newer reports

This also seems related to #27175, although this report predates it and I am currently on 26.602.4764.0. The overlapping symptoms are:

  • project chats disappearing or showing empty
  • local state/sidebar/index handling problems
  • queue/running work being fragile when Desktop crashes
  • clearing session files not necessarily fixing the Desktop UI state

What would help

In addition to atomic/crash-safe file writes, I think the Desktop app needs a supported recovery/reindex path for local state, for example:

  • validate and repair .codex-global-state.json from state_5.sqlite + existing rollout files
  • rehydrate project sidebar entries from active local threads by workspace root
  • migrate old local thread_source IS NULL Desktop threads to the current expected source kind, or include them in local recovery/search
  • avoid relying on pins as the only practical way to hydrate old local project threads
  • persist composer drafts and attachment state before any UI-blocking operation
  • on startup after forced termination, detect incomplete state writes and offer recovery instead of silently showing empty projects

The current workaround requires manually inspecting and patching JSON/SQLite/session files, which is risky and not something users should have to do.

dudantas · 1 month ago

Additional update: GUI freeze improved after local log/plugin cleanup

I have one more data point from the same affected Windows profile. The Desktop app later started visually freezing / becoming unresponsive for many seconds, sometimes close to a minute, without a clear Windows Application Hang event being recorded.

During one live freeze/startup investigation on the updated Windows app package:

OpenAI.Codex_26.608.1337.0_x64__2p2nqsd0c76g0

I observed:

  • Codex.exe was still marked as responding by Windows, but it was temporarily consuming high CPU and significant disk reads.
  • %USERPROFILE%\.codex\logs_2.sqlite was about 668 MB.
  • %USERPROFILE%\.codex\logs_2.sqlite-wal had grown to about 186 MB.
  • Simple local log aggregation queries were very slow / timed out during earlier inspection.
  • The log repeatedly contained:
failed to load plugin: plugin is not installed plugin="browser-use@openai-bundled"

The local config.toml still had browser-use@openai-bundled enabled, but the local bundled plugin cache only contained browser, chrome, and computer-use, not browser-use.

A conservative mitigation helped noticeably:

  1. Closed Codex Desktop.
  2. Archived only diagnostic log files:
  • %USERPROFILE%\.codex\logs_2.sqlite
  • %USERPROFILE%\.codex\logs_2.sqlite-wal
  • %USERPROFILE%\.codex\logs_2.sqlite-shm
  • %USERPROFILE%\.codex\log\codex-tui.log
  1. Disabled the missing browser-use@openai-bundled plugin entry in config.toml.
  2. Restarted Codex Desktop.

After that, the app appeared noticeably more responsive.

I did not touch chat/session state during this mitigation, specifically not:

  • state_5.sqlite*
  • sessions/
  • archived_sessions/
  • session_index.jsonl
  • history.jsonl
  • .codex-global-state.json

This suggests there may be a second contributing factor beyond the crash-safety/sidebar recovery problem: a large local log database plus repeated loading attempts for a configured-but-missing bundled plugin can make the Desktop app appear frozen or slow, and that freeze can lead to the destructive Windows End Process flow described above.

Follow-up: I later hit a stronger version of the same failure on 26.609.4994.0: a Crashpad dump was produced, the app restarted/updated from logs referencing 26.609.3341.0, app-server initialization hit restart-required and took about 127 seconds to recover, and active chats/tasks stopped. I added the concrete timeline and log snippets in a newer comment below.

dudantas · 1 month ago

Additional update: Desktop crash/restart while active chats were running

This happened again on the same Windows profile, this time after the app had updated to:

OpenAI.Codex_26.609.4994.0_x64__2p2nqsd0c76g0
Version: 26.609.4994.0

From the UI side, it initially looked like Codex was still running but the GUI was not becoming visible. The process list showed Codex.exe processes still alive, including one process with a valid main window handle. After the UI came back, the active chats/tasks had stopped and I had to restart the work.

Local evidence suggests this was not just an off-screen or minimized window:

  • Previous desktop log paths reference OpenAI.Codex_26.609.3341.0.
  • A Crashpad dump was created at 2026-06-15 10:04:50 local time:

%LOCALAPPDATA%\Packages\OpenAI.Codex_2p2nqsd0c76g0\LocalCache\Roaming\Codex\web\Codex\Crashpad\reports\efe6e255-9215-4de3-a655-dcdb4c3361e6.dmp

  • The new Codex.exe process started at 2026-06-15 10:04:56 local time.
  • The new desktop log shows app-server startup at 2026-06-15T13:04:58Z.
  • Initialization hit initialize_handshake_timeout with connectionError={"code":"restart-required"}.
  • App-server initialization only completed around 2026-06-15T13:07:07Z, after about 127 seconds.

The old pre-restart log had repeated messages immediately before the crash/restart window:

Failed to register chat process notification
Unexpected token '\^@' ... is not valid JSON
Item not found in turn state

There were also in-app browser/sidebar errors around the same period, including Cannot find context with specified id and ERR_FAILED (-2) loading 'about:blank', followed by browser sidebar page teardown.

I am not attaching the raw dump or full logs publicly because they may contain local paths, conversation ids, and other sensitive data. The important symptom is that Codex can appear to still have processes alive, then restart/update underneath active work, and the active chats/tasks are lost or interrupted. This seems to reinforce the need for crash-safe session/process recovery, not only sidebar reindexing.

safal207 · 26 days ago

This issue maps closely to LS work on durable trajectories, crash-safe persistence, integrity evidence, and deterministic recovery.

A useful distinction is:

state file exists
≠ state is complete
≠ indexes agree
≠ the newest timestamp is trustworthy

A crash-safe local state model could treat SQLite, rollout files, session indexes, configuration, and UI projections as separate materializations of one durable trajectory.

authoritative event history
→ thread registry
→ workspace index
→ sidebar/project projection
→ cached configuration state

The central invariant would be:

«After an abrupt shutdown, Codex should recover from the newest internally consistent committed state—not from whichever file happens to have the latest modification time.»

A possible checkpoint manifest:

{
"schema_version": "local-state-checkpoint/v0.1",
"checkpoint_id": "checkpoint-20260624-1842",
"created_at": "2026-06-24T18:42:11Z",
"generation": 1842,
"components": {
"state_db": {
"path": "state_5.sqlite",
"digest": "sha256:...",
"transaction_sequence": 91842
},
"global_state": {
"path": ".codex-global-state.json",
"digest": "sha256:...",
"generation": 1842
},
"session_index": {
"path": "session_index.jsonl",
"digest": "sha256:...",
"last_sequence": 7712
},
"rollout_registry": {
"count": 791,
"digest": "sha256:..."
}
},
"commit_status": "COMMITTED"
}

A safe write sequence could be:

write temporary file
→ flush file
→ fsync
→ validate parse and schema
→ atomic rename
→ fsync parent directory
→ update checkpoint manifest

The runtime should never replace a rich valid projection with a minimal default merely because startup encountered an incomplete write.

A recovery process could be:

discover candidate states
→ reject incomplete/uncommitted generations
→ validate digests and schemas
→ compare registries
→ detect impossible timestamps
→ reconstruct derived indexes
→ publish recovery report

A structured drift report might look like:

{
"schema_version": "state-reconciliation-report/v0.1",
"checkpoint_id": "checkpoint-20260624-1842",
"status": "DRIFT_DETECTED",
"findings": [
{
"component": ".codex-global-state.json",
"finding": "PROJECTION_INCOMPLETE",
"observed_projects": 1,
"recoverable_projects": 27
},
{
"component": "session_index.jsonl",
"finding": "MISSING_THREAD_REFERENCES",
"count": 675
},
{
"component": "thread timestamp",
"finding": "IMPOSSIBLE_FUTURE_TIME",
"observed": "7026-02-04T18:32:49Z"
}
],
"decision": "REBUILD_DERIVED_PROJECTIONS"
}

Another useful invariant:

«UI indexes and sidebar state should be treated as rebuildable projections, not as the sole source of truth for whether conversations exist.»

For example:

project view says “No chats”

  • active thread rows exist
  • matching rollout files exist

→ projection is stale
→ rebuild index

not:

“No chats”
→ assume conversations were deleted

Timestamp handling should also be evidence-based. A future timestamp should not automatically win conflict resolution.

timestamp > current time + allowed skew
→ INVALID_TIME_EVIDENCE
→ exclude from freshness ordering

Configuration recovery should be version-bound:

{
"config_snapshot": {
"schema_version": 7,
"writer_version": "26.602.4764.0",
"parser_compatibility": [
"26.602.x"
],
"digest": "sha256:..."
}
}

This helps prevent an older or partial writer from restoring a value the installed parser cannot accept.

A deterministic conformance fixture could test:

  1. process terminates during JSON write;
  2. power loss occurs before atomic rename;
  3. power loss occurs after rename but before checkpoint commit;
  4. SQLite contains threads missing from the UI projection;
  5. rollout file exists without a matching registry row;
  6. config snapshot contains a value unsupported by the current parser;
  7. timestamp is thousands of years in the future;
  8. newest file is corrupt but the previous generation is valid;
  9. recovery rebuilds projects and pins without duplicating threads;
  10. running recovery twice produces the same result.

A supported command such as:

codex doctor --reconcile-state

could generate a redacted report first, then apply only deterministic repairs:

SCAN
→ REPORT
→ BACKUP
→ REPAIR
→ VERIFY
→ COMMIT

Related LS work:

  • causal audit:

https://github.com/safal207/LS/issues/594

  • evidence gates:

https://github.com/safal207/LS/issues/595

  • deterministic replay:

https://github.com/safal207/LS/issues/597

  • recovered continuation state:

https://github.com/safal207/LS/pull/651

Would a small vendor-neutral "StateCheckpointManifest" and crash-recovery conformance fixture help test atomic persistence, cross-store drift detection, timestamp validation, and deterministic projection rebuilding?

dudantas · 5 days ago

July 14-15 recurrence on 26.707.8479.0: UI hang, abrupt restart, and persistent NUL process cache

This happened again on the same Windows profile with a much newer package:

OpenAI.Codex_26.707.8479.0_x64__2p2nqsd0c76g0

This recurrence was not caused by a power loss. The Desktop UI became unresponsive while tasks were running and Windows displayed the standard "not responding" flow. While its confirmation prompt had focus, a stray Space/Enter keypress intended for the composer confirmed End Process. A single accidental keypress therefore terminated the app and stopped the running turns; the tasks had to be resumed manually.

Timeline and crash evidence

For the latest occurrence on July 15 (local time, UTC-03:00):

intermediate AppModel activation PID 24152:       09:54:23.415
previous root ChatGPT.exe PID 17140 last log: 09:56:56.715
new root ChatGPT.exe PID 35372 created:          09:57:04.755
gap from the previous root's last log to the new root: approximately 8 seconds

There was therefore an intermediate package activation before the previous root stopped, rather than a simple one-process transition. The old log ended abruptly without a normal shutdown sequence. However, I found no corresponding:

  • Windows Application Error event 1000;
  • Windows Application Hang event 1002;
  • WER report or CrashDump;
  • new Crashpad dump.

The new process entered the same packaged-app container. This looks like abrupt process termination followed by a quick relaunch, rather than a documented native crash.

Error burst immediately before termination

During the 09:56:00-09:56:56.715 portion of the old process log there were 171 lines, including:

107 error-level records
73 events for an unknown conversation
30 "Conversation state not found" records
4 JSON/NUL parse errors

From 09:52:00 until termination there were 320 error-level records, including 227 unknown-conversation records, 87 missing-conversation-state records, and 22 JSON/NUL parse errors. These categories overlap, so their subtotals are not additive. I cannot prove that this error burst caused the UI hang, but it coincided with this occurrence and the log ended immediately afterward. The NUL parse failures themselves have recurred across multiple runs.

Persistent all-NUL chat_processes.json

I found a concrete persistent corruption that was not included in my original report:

file: %USERPROFILE%\.codex\process_manager\chat_processes.json
size: 13,445 bytes
content: every byte is 0x00
last modified: 2026-06-06 00:31:03 local time
SHA-256: 708E86177F15E191D0622C42434FCC7E09C401D00BC003E2B3242DD02EEE59DB

The Desktop app has continued attempting to parse this same invalid file across upgrades and repeatedly logs JSON parse failures. Inspection of the currently packaged JavaScript shows that the reader treats ENOENT as an empty process-record list. With invalid JSON, parsing fails and the higher-level handler repeatedly logs the failure. The writer recreates the directory/file with a JSON array when it next persists records.

This file is a process-association cache, not the durable conversation store. A conservative local repair is therefore to close the app completely and move the all-NUL file to a dated backup, leaving it absent so the implemented ENOENT fallback yields an empty list; the normal writer can then recreate it. I am preserving the original file for diagnostics.

Log database growth and integrity checks

Shortly after the recurrence:

logs_2.sqlite:     985.24 MiB
logs_2.sqlite-wal:  45.72 MiB
main DB growth: approximately 91.6 MiB since the previous day

PRAGMA quick_check(1) returned ok for both logs_2.sqlite and state_5.sqlite. The log database contains diagnostic logs separately from the conversation state database.

The important recovery result is that this occurrence did not delete the interrupted conversations:

  • state_5.sqlite passed quick_check;
  • .codex-global-state.json and its backup both parsed successfully;
  • session_index.jsonl parsed successfully;
  • the rollout files for the interrupted tasks still existed and ended in valid JSON.

The tasks were interrupted, but their persisted history remained recoverable. The app did not automatically continue the running turns after relaunch.

One workspace volume was also critically low on free space at the time, so I cannot rule out additional I/O pressure as a contributor to the hang. That does not explain the long-lived all-NUL process cache, and forced termination still needs a deterministic recovery path for active tasks and local state.

What this adds to the original report

The failure mode is broader than physical power loss:

  1. the UI can hang during ordinary use;
  2. the Windows default End Process flow can turn that hang into an ungraceful termination;
  3. an internal process-manager JSON file can remain entirely NUL-filled across multiple app upgrades;
  4. repeated parse/state-routing errors and a rapidly growing log database accumulate before termination;
  5. durable conversation data survives, but running work is not automatically recovered.

This reinforces the need for atomic writes plus startup validation/quarantine of invalid local state files. A startup check could detect an all-NUL process_manager/chat_processes.json, preserve it as a diagnostic artifact, rebuild the process cache, and reconcile still-running/interrupted turns from durable conversation state instead of repeatedly parsing the same invalid file.