Repository navigation
[Windows][WSL] threads.cwd stores WSL paths joined onto the current drive (/mnt/e/test → C:\mnt\e\test), breaking thread resume #42292
Description
What version of Codex are you using?
Codex App on Windows with runCodexInWindowsSubsystemForLinux = true (Agent Environment = WSL).
Affected threads rows in state_5.sqlite span many CLI versions:
0.132.0, 0.137.0, 0.142.0, 0.142.2, 0.142.4, 0.142.5,
0.144.0-alpha.4, 0.147.0-alpha.6.6
Native Windows CLI used for the failing resume: v0.152.1.
Linux CLI used for the diagnostics below: codex-cli 0.145.0 / Codex Doctor v0.145.0 · linux-x86_64.
What subscription do you have?
ChatGPT-authenticated Codex account. Exact tier is not part of local diagnostics.
What platform is your computer?
- Host: Windows,
CODEX_HOME = C:\Users\<user>\.codex - Agent environment: WSL2, Ubuntu 22.04.5 LTS, kernel
6.18.33.2-microsoft-standard-WSL2 - In WSL mode the same
CODEX_HOMEis reached over DrvFs as/mnt/c/Users/<user>/.codex
What issue are you seeing?
When Codex runs in WSL mode, the POSIX cwd of a thread is written into the
threads table of state_5.sqlite without any WSL→Windows path mapping.
Instead of mapping /mnt/<drive>/<path> to <drive>:\<path>, the value is
treated as a drive-relative absolute path and joined onto the current drive,
producing paths that do not and cannot exist:
rollout JSONL session_meta.payload.cwd (correct) |
threads.cwd in state_5.sqlite (corrupted) |
|---|---|
/mnt/e/test |
C:\mnt\e\test |
/mnt/c/Users/<user> |
\\?\C:\mnt\c\Users\<user> |
/mnt/c/Users |
\\?\C:\mnt\c\Users |
/mnt/c/Users/<user>/.codex |
\\?\C:\mnt\c\Users\<user>\.codex |
Note the second row: /mnt/c/Users/<user> already points back at the Windows
C: drive, yet it is re-joined onto C: and gains a spurious mnt\c segment.
The transcript on disk is fine — only the SQLite thread index is wrong. Since
resume reads the index rather than the JSONL, the bad value is what surfaces:
opening such a thread from the native Windows CLI shows
directory: C:\mnt\e\test
and the resume fails before the session is usable.
Scale on one machine
threads rows total : 575
cwd correctly kept as POSIX (/mnt/...) : 531
cwd corrupted into <drive>:\mnt\... : 29
cwd natively Windows : 15
The 29 corrupted rows come from both source = 'cli' and source = 'vscode'
and from 8 distinct CLI versions, so this is not a one-off regression of a
single build.
Control experiment: same thread, same config, only the resume environment differs
The corrupted cwd is not cosmetic. Resuming the same thread behaves
differently depending on where resume runs, with everything else held constant
(same CODEX_HOME, same config.toml, same account, same provider):
| resume from | result |
|---|---|
| Codex App with the WSL agent environment | works, thread resumes normally |
native Windows PowerShell, codex resume <rollout.jsonl> |
fails |
The native-Windows failure:
Error: Failed to resume session from \\?\C:\Users\<user>\.codex\sessions\<...>.jsonl:
thread/resume failed during TUI bootstrap: thread/resume failed:
failed to load configuration: Model provider `OpenAI` not found (code -32600)
The TUI header shows the corrupted directory before it fails:
model: loading /model to change
directory: C:\mnt\e\test
permissions: YOLO mode
The provider itself is healthy. [model_providers.OpenAI] is present in
config.toml; codex doctor reports config.toml parse ok and
default model provider OpenAI; and the same provider resumes the same thread
without trouble from the WSL side. Two things were ruled out separately by
constructing minimal CODEX_HOME fixtures:
- a provider defined without
base_urlstill loads fine (✓ config loaded),
so the missingbase_urlon this machine is not the trigger; - only a wholly absent provider definition reproduces a config-load failure.
So Model provider not found looks like a downstream symptom of a cwd that
cannot exist on the target platform, rather than a configuration problem in its
own right.
What steps can reproduce the bug?
- In Codex App on Windows, set the Agent Environment to WSL
(desktop.runCodexInWindowsSubsystemForLinux = true). - Start a thread whose cwd is a WSL-visible Windows drive path, e.g.
/mnt/e/test. - Inspect the persisted rollout and the index for the same thread id:
# transcript — correct
rg -n '"cwd"' ~/.codex/sessions/<yyyy>/<mm>/<dd>/rollout-<...>.jsonl | head -1
# index — corrupted
sqlite3 ~/.codex/state_5.sqlite \
"select id, source, cli_version, cwd from threads where id='<thread-id>';"Observed: JSONL says /mnt/e/test, the threads row says C:\mnt\e\test.
- Resume that same thread from a native Windows shell:
codex resume C:\Users\<user>\.codex\sessions\<yyyy>\<mm>\<dd>\rollout-<...>.jsonl
It fails with failed to load configuration: Model provider ... not found,
and the TUI header shows directory: C:\mnt\e\test. Resuming the same
thread from the WSL side succeeds.
A bulk check across the whole table:
select cwd, count(*), group_concat(distinct cli_version)
from threads
where cwd glob '[A-Za-z]:\mnt\*' or cwd glob '\\?\[A-Za-z]:\mnt\*'
group by cwd order by 2 desc;What is the expected behavior?
- When Codex runs under WSL, a POSIX cwd persisted to
threads.cwdshould
either be stored verbatim as POSIX, or be mapped correctly
(/mnt/<drive>/<path>→<drive>:\<path>) — never joined onto the current
drive to form<drive>:\mnt\<drive>\.... resumeshould reconcilethreads.cwdagainst
session_meta.payload.cwdin the rollout JSONL when the two disagree, and
prefer the transcript, which is written correctly.codex doctorshould be able to detect and repair thread rows whosecwd
cannot exist on the current platform. There is currently no supported
reindex/repair path (related: Codex leaves valid rollout files unindexed in state DB and lacks supported reindex repair #31433).- If a thread genuinely cannot be resumed from the other environment, the error
should name the real cause (unusable/unmappedcwd) instead of surfacing as
failed to load configuration: Model provider ... not found, which sends users
to edit aconfig.tomlthat is already correct.
Additional information
Secondary finding: SQLite is not reliably accessible from the WSL side
In WSL mode the CLI reaches CODEX_HOME over DrvFs (/mnt/c/...). Every
SQLite database there fails to open from the Linux side:
state DB .../state_5.sqlite · integrity error: (code: 4618) disk I/O error
log DB .../logs_2.sqlite · integrity error: (code: 4618) disk I/O error
goals DB .../goals_1.sqlite · integrity error: (code: 4618) disk I/O error
memories DB .../memories_1.sqlite · integrity error: (code: 4618) disk I/O error
thread history DB integrity error: (code: 4618) disk I/O error
rollout DB read error: (code: 4618) disk I/O error
4618 is SQLITE_IOERR_SHMOPEN — DrvFs does not support the shared-memory
mapping WAL mode requires.
The databases themselves are not damaged. Copying the same file to a native
ext4 path and re-running the check passes:
| location | PRAGMA integrity_check |
|---|---|
in place on /mnt/c/... (DrvFs) |
disk I/O error |
byte-identical copy on ext4 (/tmp) |
ok |
So in WSL mode, index writes to state_5.sqlite are performed against a store
the Linux process cannot reliably read or write. This is a plausible contributing
factor to the stale/incorrect index rows above, and it makes codex doctor report
a hard state failure that no local repair can clear while the app stays in WSL mode.
Related issues (overlapping symptoms, different failure points):
- Codex Desktop automation thread resume fails when state_5.sqlite has blank model_provider despite JSONL session_meta provider #29083 — resume fails when
state_5.sqlitehas a blankmodel_provider
while the JSONL has a valid one. Same class of "index disagrees with transcript",
different column. - Windows Codex app + WSL: UNC cwd breaks terminal, Windows config leaks into WSL, and worktrees need a WSL-native CODEX_HOME #18506 — Windows Codex app + WSL: UNC cwd breaks terminal, Windows config leaks into WSL.
- Browser Use Node REPL fails in Windows Desktop app with WSL workspace due to unmapped sandboxCwd #29639 — WSL workspace fails due to unmapped
sandboxCwd. - [Windows + WSL] Cannot create projects – AbsolutePathBuf deserialized without a base path #41463 —
[Windows + WSL] AbsolutePathBuf deserialized without a base path. - Codex leaves valid rollout files unindexed in state DB and lacks supported reindex repair #31433 — rollout files left unindexed, no supported reindex repair.
Suggested fix direction
The join looks like it goes through a "resolve against a base directory" path
that receives a POSIX absolute path but no WSL-aware base. Either the value
should never be resolved on the Windows side, or the resolver needs a
/mnt/<drive> → <drive>:\ rule before joining. A one-time migration that
rewrites existing <drive>:\mnt\<drive>\... rows from the corresponding rollout
session_meta.payload.cwd would clear the accumulated bad rows.
Activity
github-actions commentedon Sep 2, 2026
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
/mnt/d/...toC:\d\..., breaking file tree and Project creation #42211Powered by Codex Action