[Windows] thread/archive schedules one rollout twice when SQLite uses a verbatim path alias
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What version of the Codex App are you using (From “About Codex” dialog)?
- Originally reproduced with Codex Desktop app-server 0.148.0-alpha.15 in the 26.814.x Desktop package line. - Still reproduced after the official update to Desktop package 26.818.2441.0, which bundles app-server 0.148.0-alpha.21. - Updated bundled codex.exe SHA-256: 18FBF51F77ADFC543C9D86C78C0A54553F89BA79236ED8B0A3C48E2A3B4F010E.
What subscription do you have?
Not relevant to this local filesystem operation.
What platform is your computer?
Windows 11 x64, Microsoft Windows NT 10.0.26200.0.
What issue are you seeing?
On Windows, thread/archive fails with:
failed to archive session: thread-store internal error: failed to archive thread:
The system cannot find the file specified. (os error 2)
The rollout exists and is readable. The failure occurs when SQLite stores the rollout path using the Windows verbatim spelling:
\\?\C:\synthetic\codex-home\sessions\YYYY\MM\DD\rollout-....jsonl
while RolloutReferenceIndex::scan discovers the same physical file using the ordinary spelling:
C:\synthetic\codex-home\sessions\YYYY\MM\DD\rollout-....jsonl
In rust-v0.148.0, archive_thread_with_paths deduplicates these paths with raw PathBuf equality:
if !rollout_paths.contains(&selected_rollout_path) {
rollout_paths.push(selected_rollout_path.clone());
}
Both aliases therefore enter rollout_moves. scoped_rollout_path resolves both aliases to the same physical source file. The first rename succeeds; the second rename tries to move the now-missing source, returns os error 2, and rollback restores the first move. The user sees an archive failure even though the source file was present.
What steps can reproduce the bug?
The following A/B was run only in an isolated temporary CODEX_HOME with a synthetic thread and rollout:
- Create one valid minimal session_meta rollout under sessions/YYYY/MM/DD.
- Create a consistent test state database containing the synthetic thread.
- Store its rollout_path using the verbatim Windows spelling shown above.
- Call the official app-server thread/archive JSON-RPC method.
- Observe the exact os error 2 and verify rollback leaves the source active.
- Reset the isolated fixture.
- Change only the synthetic rollout_path to the ordinary C:... spelling.
- Call the same binary with the same thread/archive request.
- Archive succeeds, the rollout moves once to archived_sessions, and the isolated metadata records archived=1.
A separate Rust std::fs::rename probe confirmed that one rename can mix ordinary and verbatim path spellings successfully. The namespace itself is not the failing invariant; duplicate physical-file scheduling is.
No real Codex database, rollout, task, installation, or configuration was modified for this reproduction.
The isolated verbatim-path case was rerun after updating to Desktop 26.818.2441.0 / app-server 0.148.0-alpha.21. It still returned the same thread-store os error 2. Verification after the failure found one active synthetic rollout, zero archived synthetic rollouts, and the isolated SQLite row remained archived=0 with no archived_at value. Testing stopped on that first failure; no real task was used.
What is the expected behavior?
Archive should identify rollout files by normalized/canonical filesystem identity before deduplication and before constructing rollout_moves. One physical rollout must be moved exactly once regardless of whether discovery and SQLite use ordinary and verbatim Windows path aliases.
Additional information
- Normalize or canonicalize filesystem identity before deduplicating rollout_paths.
- Ensure the selected rollout maps to the deduplicated destination.
- Add a Windows regression where the reference-index scan supplies an ordinary path and SQLite supplies the equivalent \?\ path.
- Assert that exactly one move is scheduled and thread/archive succeeds.
The current main branch appears to use a newer single-path archive flow than rust-v0.148.0. Please confirm whether that refactor already fixes this case and, if so, which Desktop build contains the fix. A dedicated Windows alias regression would prevent recurrence.
Source pointers
- Affected tagged implementation:
https://github.com/openai/codex/blob/rust-v0.148.0/codex-rs/thread-store/src/local/archive_thread.rs - Current main implementation:
https://github.com/openai/codex/blob/main/codex-rs/thread-store/src/local/archive_thread.rs
Duplicate search
No matching existing issue was found. These reports are related to archive/session handling but describe different failure modes:
- https://github.com/openai/codex/issues/25713
- https://github.com/openai/codex/issues/37058
- https://github.com/openai/codex/issues/23851
- https://github.com/openai/codex/issues/24944
- https://github.com/openai/codex/issues/23002
Privacy
This report intentionally omits real task IDs, project names, user paths, chat content, logs, credentials, and raw rollout data.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Compare the affected rust-v0.148.0 implementation in codex-rs/thread-store/src/local/archive_thread.rs with the current main version, then trace the thread/archive entry point and rollout path handling. Add the Windows alias regression described in the issue; done means one physical rollout produces exactly one move and thread/archive succeeds with the metadata marked archived.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust, sqlite
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100