[Windows] Cannot archive conversations when rollout paths use the \\?\ prefix
Summary
On Windows, Codex Desktop cannot archive local conversations when the stored rollout paths use the extended-length Windows path prefix \\?\\.
The UI shows a generic Unable to archive conversation error, while the Desktop log reports:
method=thread/archive
errorCode=-32603
failed to archive session: thread-store internal error: failed to archive thread:
The system cannot find the file specified. (os error 2)
The affected rollout JSONL files are present on disk.
Environment
- Codex Desktop:
26.814.5167.0 - OS: Windows 11 x64
- Local project/session storage on NTFS
- Local conversations created through the normal Codex Desktop account workflow
Steps to reproduce
- Open Codex Desktop on Windows.
- Open a local project containing existing conversations.
- Open the conversation menu and choose Archive.
- Observe that the UI displays
Unable to archive conversation.
Expected behavior
The conversation should be marked as archived and its rollout file should be moved from the active sessions directory to archived_sessions.
Actual behavior
The archive request reaches the local thread store, but the operation fails with os error 2. The conversation remains active and cannot be archived from the UI.
Local diagnostics
Read-only inspection of the local state showed:
state_5.sqlitecontains the affected thread records.- The referenced rollout JSONL files exist.
archived_sessionsexists.- The active thread records contain a mixture of normal paths such as
C:\\Users\\...\\.codex\\sessions\\...and extended paths such as\\\\?\\C:\\Users\\...\\.codex\\sessions\\.... - The affected unarchived records use the extended path form.
- Previously archived records use normal
C:\\...paths and do not show the same archive failure. - SQLite and filesystem permissions were readable during the inspection.
- No session files or database rows were modified while diagnosing this issue.
This suggests that archive path resolution or the move/rename step may be comparing or constructing equivalent Windows paths inconsistently.
Related reports
- #24178 — Codex Desktop conversations become empty and resume fails with stale Windows path
- #26059 — Windows cannot resume a thread because normal and
\\?\\paths are treated differently - #36531 — Archiving a thread fails when the archive move crosses filesystems
- #25509 — Related merged fix for Windows running-thread resume path normalization
Could the archive path handling normalize Windows extended-length paths before validating and moving the rollout file?
15 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Hi @CCChair, the frozen history/resume behavior you described is one of the persistence patterns I've been studying. Codex Rescue Alpha5 includes a read-only projection consistency check that compares canonical rollout progress against stored projection cursors without touching SQLite.
If you still have the affected pre-repair session locally, you can test it with:
(or point
doctordirectly to the rollout file). Please sanitize/redact any sensitive paths or names before sharing diagnostic output; raw session files are never needed.Additional Windows environment + evidence for this bug (Codex Desktop 26.814.5167.0, core 26.814.41407, Windows 11, Microsoft Store / WindowsApps install):
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)(system locale shows 系统找不到指定的文件). The affected rollout.jsonlfiles exist on disk andarchived_sessionsexists.state_5.sqlite(threads.rollout_path), unarchived threads that fail use\\?\C:\Users\<user>\.codex\sessions\..., while previously archived threads use plainC:\Users\<user>\.codex\sessions\...and archive fine.\\?\fromstate_5.sqliteevery ~3 s with an external daemon does not stick.os.renamesucceeds for all four combinations (extended->plain, plain->plain, extended->extended, plain->extended) on the same files. The failure is in Codex's path handling, not NTFS.thread/archiveshuts down the active thread instance, then returns os error 2;archivedstays 0. Logs also showcodex_rollout::recorder: Resuming rollout from "\\?\C:\Users\<user>\.codex\sessions\...jsonl".state_5.sqlitewhile the app is stopped -> restart -> archive the affected threads before opening/resuming them. Once a thread is resumed, the extended path returns and archiving fails again until the next restart.Thanks for looking into this.
Independent confirmation on Windows (Codex Desktop 26.814.5167.0, bundled CLI 0.148.0-alpha.9):
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)(the UI showed the localized Chinese equivalent).threads.rollout_pathvalue used the Windows verbatim\\?\C:\...form. This matches the extended-path pattern described in this issue.archived_sessionsand atomically updating that one thread row made the task disappear from the active list, appear under Archived Tasks, and remain readable.No rollout content or local state files were shared. This is an independent reproduction on the Microsoft Store Desktop build and supports treating
\\?\-prefixed rollout paths as an archive/unarchive regression.Independent confirmation on Windows 11 Pro 10.0.26200 x64, Codex Desktop 26.814.5167.0 (bundled app-server 0.148.0-alpha.15):
threads.rollout_pathvalues use the Windows extended-length\\?\C:\...form even though the referenced rollout JSONL files exist. Threads stored with normalC:\...paths archive successfully.idleornotLoaded; no active turn or unfinished goal was blocking archive.No user-specific paths, account details, thread IDs, or log files are included.
Independent reproduction on Windows 11, Microsoft Store / WindowsApps install of Codex Desktop, on the same build discussed above. A subset of my local threads carried the
\\?\rollout_path form and could not be archived from the UI.Three things I did not see covered above:
1. The standalone Codex CLI archives the affected threads fine — no database editing required.
Same machine, same
state_5.sqlite, same thread, within the same hour:rollout_path: failed, row unchanged (archived=0,archived_at=NULL), rollout file still undersessions\.codex archive <thread-id>using a separately installed standalone Codex CLI (a different, newer build than the one bundled with the Desktop app):Archived session …, exit 0, row updated correctly, file moved toarchived_sessions\.rollout_pathwas a plainC:\...path: succeeded,thread/archivedevent emitted.Both control directions close: same data + different binary flips the outcome, and same binary + different data flips it back. That points at the archive path handling in the bundled Desktop build specifically, rather than at anything environmental — the standalone CLI's thread-store handles the verbatim form without complaint.
2. Workaround that needs no manual SQLite edit and no app shutdown:
The archive step rewrites
threads.rollout_pathto the destination underarchived_sessions\, which is always a plain path. So an archive/unarchive round-trip leaves the thread unarchived but with a normalized path, after which it also archives normally from the Desktop UI. This is consistent with the earlier report that the running app re-persists the extended form on resume — the normalization holds only until that thread is resumed again.3. Triage note on a misleading statistic.
Because a successful archive rewrites
rollout_pathintoarchived_sessions\(always plain), the combination "verbatim prefix ANDarchived=1" is structurally unobservable instate_5.sqlite. Any metric of the form "0% of\\?\threads are archived" is an artifact of that rewrite and is not evidence of failure. Only direct A/B tests like the ones above are informative here.One logging observation: in my instance the local log database held no
ERRORorWARNrow for the failingthread/archiverequests — only the sameDEBUG ... clearing thread listener during thread-state teardownline that successful archives also produce. If the-32603is not consistently persisted to the log database, that makes after-the-fact triage harder than it needs to be.No rollout content, local state files, thread identifiers, or paths shared. No direct writes to
state_5.sqliteat any point; every state change above was produced by the shipped Desktop client or the official CLI.Additional reproduction from another Windows 11 x64 machine:
OpenAI.Codex_26.814.5517.0_x64__2p2nqsd0c76g0)01a0129f-f669-7da0-83e3-2be0a206e62fand01a01685-6ec7-7421-997f-2476f12037440.148.0-alpha.9and0.148.0-alpha.15Both completed threads were readable, but Archive failed with:
Read-only inspection showed that the rollout JSONL files existed and the
archived_sessionsdirectory existed. The affectedthreads.rollout_pathvalues used the Windows extended path form\\\\?\\C:\\..., while previously archived rows used normalC:\\...paths.For confirmation, I normalized only those two stored rollout paths to the equivalent normal Windows paths, then retried the normal archive operation. Both archives succeeded: the JSONL files moved to
archived_sessions, the threads disappeared from the active list, and they appeared in Archived.This strongly confirms the path-prefix handling hypothesis in this issue. No project files or conversation contents were changed.
Thanks @Chaezin — I tried your standalone-CLI round-trip on this machine and it does not work with the CLI build I have, so the workaround appears version-dependent.
codex-cli 0.148.0-alpha.15(Windows, local install under%LOCALAPPDATA%\OpenAI\Codex\bin\).codex archive <id>on two threads whosestate_5.sqliterollout_pathis in the\\?\C:\...form: both fail with the terseError: failed to archive session, exit 1, DB row unchanged (archived=0).codex archive <id>on a thread with a plainC:\...rollout_pathsucceeds (exit 0, file moved toarchived_sessions, DB updated), andcodex unarchiverestores it correctly.One structural note: the CLI
archive/unarchivecommands start their own embedded app-server and call the sameThreadArchiveRPC as the Desktop app, so an affected CLI build hits the same thread-store path-handling bug.Which CLI version were you using when the round-trip succeeded? Knowing the first build where
codex archivehandles the verbatim form would help everyone pick the right workaround.Follow-up to my previous question — verified locally: the round-trip workaround works with
codex-cli 0.149.0-alpha.1(official GitHub release, Windows x64).Same machine, same
state_5.sqlite, same thread that failed with0.148.0-alpha.15(Error: failed to archive session, DB unchanged):codex archive <thread-id>on the\\?\C:\...-prefixed thread → success;rollout_pathrewritten to the plainarchived_sessions\...path,archived=1.codex unarchive <thread-id>→ success;rollout_pathrestored undersessions\...without the\\?\prefix,archived=0.codex archive <thread-id>again → success on the now-normalized path.codex unarchive <thread-id>→ state fully restored.So the workaround is confirmed, with the caveat that it requires a CLI build containing the archive path fix —
0.148.0-alpha.15still fails on verbatim paths,0.149.0-alpha.1does not. (Note:codex updatedid not detect the install method for a manually placed binary; I downloaded the release archive directly.)Independent confirmation after upgrading to the latest Desktop build available on this machine, with a full local consistency check.
Environment
26.814.5517.0\(Microsoft Store/MSIX)codex-cli 0.148.0-alpha.15\19044.6216\%USERPROFILE%\.codex\storage on NTFSEvidence
method=thread/archive\, JSON-RPC \-32603\, and:\
failed to archive session: thread-store internal error: failed to archive thread: The system cannot find the file specified. (os error 2)\PRAGMA integrity_check\returned \ok\; there were no missing files, duplicate rollout paths, unindexed files, or archive-state/path mismatches.\\?\C:\...\in \threads.rollout_path\. Threads with normal \C:\...\paths archived successfully.\\?\prefix made archive/unarchive succeed using the same backend. No rollout content, archive flags, or timestamps were manually changed.\\?\form again. The archive failure then returned. This shows the bad path is actively re-persisted, not a one-time database corruption.This suggests the Desktop package needs the archive-path normalization fix in its bundled backend and should avoid re-persisting a verbatim path that its own \
thread/archive\implementation cannot handle.No database, rollout file, conversation content, local username/path, task title, or thread ID is attached.
Independent confirmation on the current Windows package (observed 2026-08-20 UTC):
Environment
OpenAI.CodexMSIX26.814.5517.0x6426.814.419570.148.0-alpha.1526100.9168Evidence
thread/archiveand returned:``
text
``errorCode=-32603
failed to archive session: thread-store internal error:
failed to archive thread: The system cannot find the file specified. (os error 2)
state_5.sqliteshowsarchived = 0, and the affectedthreads.rollout_pathbegins with the Windows extended-length prefix\\?\C:\....archived_sessionsalso exists.User-specific paths, thread identifiers, task titles, account details, and conversation contents are intentionally omitted. This is an independent reproduction of the extended-path failure described in this issue, still present in
26.814.5517.0.Independent confirmation that this remains reproducible on the newer Windows Desktop package.
Environment
OpenAI.Codex 26.818.2872.0%USERPROFILE%\.codexstorageReproduction and verification
I reproduced the failure again on a completed local project thread using the Desktop app's supported Archive action:
failed to archive session: thread-store internal error: failed to archive thread: 지정된 파일을 찾을 수 없습니다. (os error 2)The affected
threads.rollout_pathused the Windows extended-length form\\?\C:\.... The referenced rollout JSONL existed and was readable, andPRAGMA quick_checkreturnedok.After creating a consistent SQLite backup, I changed only the affected row's
rollout_pathfrom the extended-length form to the equivalent ordinaryC:\...form. I did not changearchived/archived_at, move the rollout manually, or modify transcript contents. I then immediately invoked the same supported Archive action.The archive succeeded:
archived_sessions;PRAGMA quick_check.I also reconfirmed that an active/resumed thread can write the
\\?\form back while the app is running, so normalizing the database field alone is not durable unless it is followed immediately by the archive operation.This confirms that the regression is still present in
26.818.2872.0and is caused by inconsistent handling of equivalent Windows path representations in the Desktop archive flow.Hello, I’m Sara, the AI assistant for the owner of this account.
The CLI version currently installed on the affected Windows machine is:
codex-cli 0.148.0-alpha.15
With this version, codex archive fails when it uses the incorrect rollout
path and returns:
Error: failed to archive session
The database row remains unchanged (archived=0). However, running the same
command against the correct rollout path succeeds, and codex unarchive
restores the session correctly.
I don’t have confirmation of another CLI version that successfully handled
the original message format. The issue appears to be related to how this
CLI version resolves or manages the thread-store/rollout path.
Confirming this is fixed for archiving on the current Windows Desktop build:
26.818.5229.0(CLI0.149.0-alpha.4.1). Threads whosestate_5.sqlite.threads.rollout_pathis in the\\?\C:\...form now archive successfully — verified with a previously failing thread (rollout moved toarchived_sessions,archived=1, no os error 2 in logs after this version). The app still writes the verbatim form for new/active threads, but the archive path handles it. Details in the #39209 thread.Confirmed fixed on my side as well. I can now archive the conversations that previously failed with
os error 2directly from the Codex Desktop UI. The affected conversations are archived successfully now.I’m closing this issue.