Codex Desktop Windows: archive fails with os error 2 when state_5.sqlite rollout_path uses \\?\ prefix
Summary
On Windows, local Codex Desktop thread archiving can fail with:
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)
On my machine this reproduces when state_5.sqlite.threads.rollout_path points at an existing rollout JSONL using a Windows extended-length path prefix (\\?\C:\...). The rollout file exists and is readable. If I back up state_5.sqlite, remove only the leading \\?\ prefix from that thread row's rollout_path (and cwd for consistency), then immediately call archive again, the same thread archives successfully.
This looks related to the existing archive/session path-consistency issue family, but I did not find an exact report for the rollout_path = \\?\... trigger on Windows.
Environment
- Platform: Windows 11 x64
- Codex Desktop client observed in logs:
26.814.41957 - Affected local thread rows include
cli_version = 0.148.0-alpha.15and0.148.0-alpha.9 - Local state database:
%USERPROFILE%\.codex\state_5.sqlite - Logs database:
%USERPROFILE%\.codex\logs_2.sqlite - Active sessions directory:
%USERPROFILE%\.codex\sessions\... - Archive directory:
%USERPROFILE%\.codex\archived_sessions\...
Reproduction From Local State
For a completed/notLoaded local thread:
- Confirm the thread row is unarchived and the rollout path starts with
\\?\:
SELECT
id,
archived,
quote(substr(rollout_path, 1, 6)) AS rollout_prefix,
quote(substr(cwd, 1, 6)) AS cwd_prefix,
substr(rollout_path, 1, 100) AS rollout_head,
cli_version
FROM threads
WHERE id = '<thread-id>';
Observed before repair:
archived = 0
rollout_prefix = '\\?\C:'
cwd_prefix = '\\?\C:'
rollout_head = \\?\C:\Users\<user>\.codex\sessions\YYYY\MM\DD\rollout-...-<thread-id>.jsonl
cli_version = 0.148.0-alpha.15
- Confirm the physical rollout JSONL exists and is readable after stripping the
\\?\prefix. - Try to archive the thread from Codex Desktop / app thread API.
Observed error:
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)
- Back up
state_5.sqlite. - Remove only the leading
\\?\prefix for that one notLoaded/idle thread:
UPDATE threads
SET
rollout_path = CASE
WHEN substr(rollout_path, 1, 4) = '\\?\' THEN substr(rollout_path, 5)
ELSE rollout_path
END,
cwd = CASE
WHEN substr(cwd, 1, 4) = '\\?\' THEN substr(cwd, 5)
ELSE cwd
END
WHERE id = '<thread-id>' AND archived = 0;
- Run
PRAGMA integrity_check;and confirmok. - Archive the same thread again.
Observed after repair:
archived = 1
rollout_path = C:\Users\<user>\.codex\archived_sessions\rollout-...-<thread-id>.jsonl
source_exists = false
archived_exists = true
Important Observations
- This is not limited to old sessions. On my machine, new/current
0.148.0-alpha.15rows can also haverollout_path = \\?\.... - A one-time bulk SQL normalization is not durable. Some rows that were normalized earlier later got the
\\?\prefix written back after the thread was resumed or updated. cwd = \\?\...alone does not appear to be enough to break archive. In my local DB, many successfully archived rows still hadcwdwith a\\?\prefix. The direct failure indicator wasrollout_path = \\?\....- For successfully archived rows in my local DB, archived
rollout_pathvalues were normal paths underarchived_sessions, not\\?\.... - Recent logs also showed repeated Windows long-path related hook failures:
after_agent hook failed; continuing ... hook_name=legacy_notify error=The filename or extension is too long. (os error 206)
This hook error is not the same as the archive os error 2, but it suggests the current Windows path/string handling path has adjacent long-path issues.
Expected Behavior
Archiving should work when the thread's rollout JSONL exists and is readable, regardless of whether the persisted path uses a normal Windows path or an extended-length \\?\ path.
At minimum, Codex should normalize supported Windows path forms consistently before scope validation / filename extraction / rename, and should avoid persisting a path format that the archive path cannot later handle.
Actual Behavior
The archive operation fails with os error 2 while the rollout file exists. Normalizing the one affected row's rollout_path from \\?\C:\... to C:\... makes the same archive operation succeed immediately.
Why This May Point To Thread Store Path Handling
The current archive implementation resolves a current rollout path, scopes it under sessions, validates the rollout filename, then renames the selected rollout into archived_sessions and updates SQLite metadata:
https://github.com/openai/codex/blob/main/codex-rs/thread-store/src/local/archive_thread.rs
The observed behavior suggests one of those path handling steps is not treating \\?\C:\... and C:\... as equivalent on Windows.
Related Issues
- #26012 - Windows archive/restore path inconsistency with
The system cannot find the file. (os error 2) - #25541 - Windows archive UI / sidebar reconciliation issues
- #36531 - archive depends on filesystem rename and can fail with a low-level OS error
- #20317 - sessions vs archived_sessions path mismatch after archive/restore
- #33860 - unarchive can mutate storage then still return an internal error
- #27202 - archived local thread exists in SQLite but disappears from active and Archived UI
Privacy Note
I intentionally redacted real user names, local project paths, thread titles, and business prompts. I can provide additional redacted SQL/log excerpts if maintainers specify which fields would be useful.
2 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
补充最新复现(2026-08-21,Windows x64):
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)PRAGMA quick_checkreturnsok.\\?\\from affectedthreads.rollout_pathmakes archive succeed immediately; archive→unarchive round-trip was verified successfully.\\?\\prefix back and the archive failure returns.No raw logs, private paths, credentials, or conversation contents are attached.