[macOS Desktop] Active Goal loses persisted row, becomes unmanageable, and rewrites local rollout path to /root

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

Summary

After updating Codex Desktop and running an active Goal on an existing local macOS thread, the Goal completed one long turn but did not continue. The persisted Goal row disappeared while the turn was still running, while the Desktop UI continued to treat the Goal as active.

This produced a split-brain state:

  • Goal auto-continuation failed with goal_not_found.
  • Pause, cancel, and clear controls could not manage the Goal.
  • After force-quitting and reopening the app, the same local thread could not be restored because its state_5.sqlite.threads.rollout_path had been rewritten to a Linux /root/.codex/... path.
  • The actual macOS rollout JSONL still existed and was valid.

Manual SQLite repair was required to reopen the thread.

Environment

  • macOS 26.5 (25F71), arm64
  • ChatGPT/Codex Desktop 26.818.41509, build 6962
  • CLI version recorded by the affected thread: codex-cli 0.148.0-alpha.15
  • Current bundled CLI after restart: codex-cli 0.149.0-alpha.4.1
  • Model: gpt-5.6-sol
  • Thread type: local macOS Desktop thread, not Cloud or Remote
  • Time zone: UTC+8

Observed timeline

All times below are local UTC+8.

  1. 02:23: Goal creation succeeded.
  2. 02:2304:05: one long Goal turn ran for approximately 1 hour 42 minutes.
  3. Around 03:54: goals_1.sqlite was recreated as a valid but empty database. The preserved prior Goal database did not have a valid SQLite header.
  4. 04:05: the turn completed. Automatic continuation immediately failed because the backend no longer had a Goal row.
  5. The Desktop UI still presented the Goal as active. Pause, cancel, and clear did not restore consistency.
  6. Around 12:00: the app was force-quit because the Goal could not be controlled.
  7. After restart, opening the thread failed because the local rollout path in state_5.sqlite pointed to /root/.codex/... instead of the existing macOS path.

The Goal persistence failure therefore happened several hours before the force-quit. The force-quit exposed the invalid rollout path but did not cause the original Goal row loss.

Errors

At automatic Goal continuation:

cannot update goal for thread ...: no goal exists
failureReason=goal_not_found
Failed to continue active thread goal

After trying to pause/clear the Goal:

thread/goal/set: no goal exists
thread/goal/clear: success, but the UI still treated the Goal as active

After restarting Desktop:

failed to resolve rollout path
`/root/.codex/sessions/.../rollout-....jsonl`:
file does not exist

Local evidence

  • The supposedly missing transcript existed under /Users/<redacted>/.codex/sessions/....
  • It was 480,201,360 bytes with 34,991 newline-delimited JSON records and passed a full JSON parse.
  • The thread row still had a macOS working directory under /Users/<redacted>/... and was classified as local, but its rollout_path used /root/.codex/....
  • A second local thread had the same /root rollout-path corruption.
  • The active goals_1.sqlite.thread_goals table was empty after the failure.
  • logs_2.sqlite also reported database disk image is malformed, with freelist/pointer-map corruption. 250,333 of 268,648 pages (93.18%) were on the freelist. Recovering reachable records produced a healthy database of about 60 MiB.
  • The conversation transcript itself was not corrupt or missing.

No full transcript, database, username, repository path, credentials, or conversation content is included in this public report.

Reproduction sequence

This is the observed sequence; I do not yet have a deterministic minimal reproducer for the database migration timing.

  1. Update Codex Desktop.
  2. Open an existing local macOS thread.
  3. Start a Goal and let it run through a long turn.
  4. Allow the active Goal to cross a Desktop/app-server storage migration or process transition.
  5. At turn completion, observe whether automatic continuation reports no goal exists while the UI still shows an active Goal.
  6. Try pause, cancel, and clear.
  7. Restart Desktop and reopen the thread.
  8. Inspect whether the local threads.rollout_path was normalized to /root/.codex/... even though the rollout exists under the macOS home directory.

Expected behavior

  • Goal persistence should be atomic with active Goal execution and storage migration.
  • UI Goal state should reconcile when the persisted Goal row is missing or reset.
  • Pause, cancel, and clear should return an actionable state instead of leaving a zombie Goal.
  • A local macOS thread must never receive a Linux /root/.codex/... rollout path.
  • Startup should detect and repair host/path mismatches when the canonical rollout exists.
  • SQLite recovery should not silently replace a damaged Goal database with an empty database while the UI continues to advertise an active Goal.

Impact

  • Long-running Goal execution stops without completing the objective.
  • The Goal cannot be paused, cancelled, or cleared.
  • Existing local chats become inaccessible.
  • Users may believe transcript data was deleted even though only metadata is wrong.
  • Manual database backup, path repair, and log-database recovery are required.

Related issues

  • #23984 — older Goal DB/schema/process mismatch; closed as completed, but this appears to be a regression/different active-migration failure.
  • #24423 — Goal operations fail around older rollout compatibility, but the current case loses an already-active Goal after a successful long turn.
  • #31074 — stale rollout paths where backing files are genuinely missing; here the rollout exists and the stored path points to the wrong operating-system home.
  • #40178 — restart/runtime transition can desynchronize durable history and the UI; adjacent but not the same Goal-store and host-path failure.
  • #28224 — historical logs_2.sqlite write amplification; the current case additionally had structural freelist/pointer-map corruption.

Please investigate:

  1. Atomicity of Goal-store migration/recovery while a Goal turn is active.
  2. Reconciliation between frontend active-Goal state and goals_1.sqlite.
  3. Host-aware normalization of local rollout paths.
  4. Startup self-healing when the indexed rollout path is wrong but the canonical JSONL exists.
  5. Automatic detection and safe reconstruction of corrupted local SQLite stores.

Sanitized timestamps and targeted log excerpts can be provided if needed.

View original on GitHub ↗

2 Comments

github-actions[bot] contributor · 5 days ago

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

  • #38854

Powered by Codex Action

EnglandLobster · 5 days ago

Clarification: this report contains two independently actionable failures.

  1. Goal persistence/UI split-brain: the active Goal row disappeared while a turn was still running, so continuation and Goal controls stopped working.
  2. Cross-host rollout-path corruption: an existing local macOS thread, whose valid transcript was present under /Users/<redacted>/.codex/sessions/..., had state_5.sqlite.threads.rollout_path rewritten to /root/.codex/sessions/.... A second local thread had the same corruption.

The second failure is not a normal “missing transcript” case: the JSONL existed and parsed successfully; only its persisted metadata pointed to the wrong operating-system home. It should be investigated independently even if it turns out not to share the Goal-store root cause. The app needs host-aware path validation/reconciliation during migration and startup.