Switching Codex from WSL to Windows-native breaks existing chats, rewrites /mnt/d paths as C:\mnt\d, and loses project associations
What issue are you seeing?
Switching the Codex Windows app from WSL execution to Windows-native execution breaks existing chats that were created while the agent environment was WSL.
The conversation history remains visible, and completely new chats created in the same Windows project work normally, but old chats cannot be continued. Sending any message in an affected chat fails with:
Invalid request: AbsolutePathBuf deserialized without a base path
The affected project physically lives on a Windows drive and was accessed from WSL through /mnt/d, so the WSL and Windows paths refer to the same folder:
WSL: /mnt/d/Programming/InvestPlanner
Windows: D:\Programming\InvestPlanner
After switching the Agent environment to Windows Native, persisted chat state was only partially / incorrectly migrated. In particular, an affected thread was rewritten to the invalid Windows path:
C:\mnt\d\Programming\InvestPlanner
rather than:
D:\Programming\InvestPlanner
The broken path was confirmed in state_5.sqlite, and Codex tool execution logged:
CreateProcessAsUserW failed: 267 (The directory name is invalid.)
cwd=C:\mnt\d\Programming\InvestPlanner
The same chat also disappeared from the InvestPlanner project group in the sidebar and was only visible under Recent chats, despite the conversation itself remaining intact.
Steps to reproduce
- On Windows, configure Codex Desktop to use WSL as the Agent environment.
- Open a project that physically resides on a Windows drive, for example:
``text``
D:\Programming\InvestPlanner
accessed from WSL as:
``text``
/mnt/d/Programming/InvestPlanner
- Create and use one or more long-running chats in that project while running under WSL.
- Switch Codex Desktop Agent environment to Windows Native and restart the app.
- Open one of the existing WSL-created chats.
- The old chat remains visible, but sending any message fails with:
``text``
Invalid request: AbsolutePathBuf deserialized without a base path
- Create a brand-new chat in the same project under Windows Native.
- The new chat works normally, confirming the Windows Native project itself is valid.
- Inspect persisted local state for the old thread.
Persisted state observed
For one affected thread, the original rollout history contained WSL paths such as:
cwd = /mnt/d/Programming/InvestPlanner
workspace root = /mnt/d/Programming/InvestPlanner
visualization root = /mnt/c/Users/<user>/.codex/visualizations/...
shell = bash
After switching to Windows Native, state_5.sqlite -> threads.cwd contained:
C:\mnt\d\Programming\InvestPlanner
instead of:
D:\Programming\InvestPlanner
threads.sandbox_policy also retained the malformed path:
C:\mnt\d\Programming\InvestPlanner
C:\mnt\d\Programming\InvestPlanner\.git
C:\mnt\d\Programming\InvestPlanner\.agents
C:\mnt\d\Programming\InvestPlanner\.codex
.codex-global-state.json -> thread-writable-roots still contained WSL roots even after the project-level root had already become a Windows path:
project root:
D:\Programming\InvestPlanner
thread writable roots:
/mnt/d/Programming/InvestPlanner
/mnt/c/Users/<user>/.codex/visualizations/...
The rollout JSONL also retained WSL-specific environment state in turn_context and world_state, including:
/mnt/d/Programming/InvestPlanner/mnt/c/Users/<user>/.codex/...- workspace roots
- sandbox / permission paths
.git,.agents, and.codexpathshost_skillsfile locationsshell = bash
Sidebar / project association problem
After partially correcting the old thread's cwd to:
D:\Programming\InvestPlanner
the conversation stopped appearing under the InvestPlanner project and was visible only in Recent chats.
The project-level state already used:
D:\Programming\InvestPlanner
while the thread still had WSL thread-writable-roots, so project/thread identity appears to depend on multiple independently persisted path representations.
Manual recovery that worked
The affected conversations were recoverable without losing chat history, but only after manually migrating all of the following persisted state while Codex was fully closed:
state_5.sqlite
threads.cwdthreads.sandbox_policy
.codex-global-state.json
thread-writable-roots- workspace/project roots where applicable
sessions/**/rollout-*.jsonl
- structured
turn_contextrecords - structured
world_staterecords - embedded WSL paths in filesystem / permission / host skill state
Path conversion used:
/mnt/d/... -> D:\...
/mnt/c/... -> C:\...
C:\mnt\d\... -> D:\...
For a batch migration of the remaining chats, the local repair changed:
SQLite threads changed: 8
Global-state paths changed: 7
Session files changed: 8
Session records changed: 95
Session strings changed: 1261
Invalid JSON lines: 0
After all structured WSL path state was migrated to Windows-native paths, the previously broken chat could be continued again.
Expected behavior
Changing the Agent environment from WSL to Windows Native should not make existing chats unusable.
Codex should provide a supported migration / rebinding flow that:
- Recognizes WSL drive mappings, for example:
``text``
/mnt/d/Programming/InvestPlanner
->
D:\Programming\InvestPlanner
- Never converts WSL paths into malformed Windows paths such as:
``text``
C:\mnt\d\Programming\InvestPlanner
- Migrates all persisted thread environment state atomically, including:
- cwd
- workspace roots
- writable roots
- sandbox / permission profiles
- rollout environment snapshots
- host skill paths
- shell/environment metadata
- Preserves project/sidebar association for existing chats.
- Preserves all conversation history and accumulated context.
- Validates the migrated paths before committing the migration.
- Creates a backup / rollback point automatically.
- Warns the user before switching execution environments if existing chats require migration.
- Ideally exposes a "Rebind / migrate this chat to the current project environment" action.
Additional information
This appears to be the inverse direction of #36608, which reports Windows-native -> WSL migration failures. This report is specifically WSL -> Windows Native.
The important distinction is that the affected repository is not inside the WSL Linux filesystem: it is a normal Windows-drive repository accessed from WSL through /mnt/d, so there is a deterministic mapping back to D:\....
The chat transcript data itself was not corrupted. The failure was caused by inconsistent execution-environment metadata spread across SQLite, global state, and rollout JSONL. A new Windows-native chat in the exact same project worked normally throughout.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Your report is a strong persisted-state migration case because the transcript survives while execution metadata diverges across SQLite/global state/rollout records. If you retained an affected pre-repair rollout,
codex-rescue==0.1.0a4can run a local read-only cross-check on the rollout itself. It will not rewrite WSL/Windows paths or modify Codex state, but it can help establish whether the durable transcript remains structurally usable and whether there are schema/tool-state findings before any migration:Please share only a sanitized summary of the status, findings, and aggregate counts. Do not post the raw rollout/database/global-state files, prompts, tool input/output, credentials, repository names, thread IDs, or private paths.
I ran the suggested read-only check with
codex-rescue==0.1.0a4against the affected pre-repair rollout.Sanitized results:
The repository check also reproduced the path translation issue:
The session metadata itself still contains the original valid WSL cwd.
This seems to further confirm that the durable transcript is structurally healthy and that the failure is caused by persisted execution/path metadata being interpreted or migrated incorrectly when switching from WSL to Windows Native, rather than transcript corruption.
For reference, the affected rollout contained 2730 valid records and no detected tool-call/schema corruption. After manually migrating the persisted WSL path state across SQLite, global state, and structured rollout environment records to Windows-native paths, the same conversation became usable again.
@inevitableLJW
Thanks for running the read-only check and for the clean reproduction of the path-translation issue — that WSL→Windows path case is addressed in the just-released 0.1.0-alpha.7.
Your diagnosis was exactly right: the durable transcript was structurally healthy (2730 valid records, no tool-call/schema corruption), and the failure was persisted WSL
/mnt/<drive>cwd metadata being misinterpreted by a Windows-native runtime —/mnt/d/<project>resolving to the bogusC:\mnt\d\<project>and failing with "cwd does not exist".Alpha7 adds field-driven path-family detection that recognizes a persisted WSL
/mnt/<drive>cwd and translates it to the correct Windows-native form (D:\<project>) instead of naively prefixingC:\. Soworkspacenow reports the translated path and the family mismatch rather than a false "cwd does not exist".To confirm on your side:
It should now surface the WSL→Windows path family and the corrected translation. Read-only as always — it won't touch the rollout or the state DB. Your manual migration of the persisted WSL path state across SQLite / global state / rollout environment records was the right repair; this just makes the diagnostic stop misreporting it.
@shleder Confirmed locally with Alpha7 after resolving a PATH collision between the older PyPI-installed
codex-rescueand the npm-installed package.The npm Alpha7 build reports:
Running the read-only workspace check against the affected pre-repair rollout now gives:
This correctly identifies the saved path family as WSL and translates
/mnt/d/<project>toD:\<project>under Windows, rather than the previous bogusC:\mnt\d\<project>interpretation.So Alpha7's diagnostic behavior looks correct on this reproduction. The underlying Codex Desktop migration issue still remains the same: switching an existing session from WSL to Windows Native left persisted execution metadata inconsistent across local state until those paths were migrated manually.
Your WSL-to-Windows reproduction informed the canonical path-identity layer. Vetto now keeps path evidence read-only and does not rewrite the persisted Codex path state.
Migration update: active Codex Rescue development has moved to Vetto: https://github.com/shleder/vetto. The standalone
shleder/codex-rescuerepository remains public as compatibility history. User installation is nownpm install --global @shleddy/vetto@next, with recovery undervetto rescue. The boundary remains read-only/copy-only and does not modify session JSONL or vendor SQLite. The newest diagnostic changes are merged into Vettomainand will be included in a later npm alpha; no source install is requested.