Switching Codex from Windows-native to WSL breaks existing project chats and preserves invalid Windows path bindings
What version of the Codex App are you using (From “About Codex” dialog)?
26.727.6591.0
What subscription do you have?
ChatGPT Plus
What platform is your computer?
Windows 11 Pro, x64 Windows build 26200 WSL2 with Ubuntu 24.04.4
What issue are you seeing?
Changing the Codex Windows app from Windows-native execution to WSL2 breaks existing chats created before the change.
The affected chats retain Windows-specific execution metadata, including:
- Windows working directories such as D:\Projects\EOE
- PowerShell as the saved shell
- Windows workspace roots
- Windows filesystem sandbox paths
- Windows permission-profile structures
When Codex attempts to open or continue these chats under WSL, it reports errors including:
AbsolutePathBuf deserialized without a base path
data did not match any variant of untagged enum PermissionProfileDe
The chat's reported working directory becomes malformed:
/mnt/c/Program Files/WindowsApps/OpenAI.Codex_26.727.6591.0_x64__2p2nqsd0c76g0/app/resources/D:\Projects\EOE
Moving the affected chat into a newly created WSL project does not rebind its working directory.
Using "Continue in new chat" preserves the conversation context, but also preserves the broken Windows execution metadata.
A completely new chat created in the WSL project works correctly and reports:
Working directory: /mnt/d/Projects/PFOS
Shell: bash
The existing conversation data is intact. The failure appears to be caused by Codex attempting to deserialize Windows-specific environment and permission records under the WSL runtime.
What steps can reproduce the bug?
- Install and open the Codex Windows app.
- Configure Codex to use Windows-native execution.
- Create a Codex project using a Windows path, for example:
D:\Projects\EOE
- Create and use a chat in that project so it accumulates conversation history, tool calls, approvals, and project context.
- Change the Codex local execution environment from Windows-native to WSL2 / Ubuntu.
- Open the existing chat created under Windows-native execution.
- Observe errors such as:
AbsolutePathBuf deserialized without a base path
data did not match any variant of untagged enum PermissionProfileDe
- Right-click the affected chat and select "Copy working directory."
- Observe a malformed path combining the Codex application resource directory with the original Windows path:
/mnt/c/Program Files/WindowsApps/OpenAI.Codex_26.727.6591.0_x64__2p2nqsd0c76g0/app/resources/D:\Projects\EOE
- Create a new Codex project using a valid WSL path, for example:
/mnt/d/Projects/PFOS
- Move the affected chat into the new WSL project.
- Select "Copy working directory" again.
- Observe that the chat still retains the old malformed Windows binding rather than using the new project's WSL working directory.
- Select "Continue in new chat."
- Observe that the continued chat preserves the conversation history but also preserves the same invalid working-directory and permission metadata.
- Create a completely new chat directly inside the WSL project.
- Ask it to report its working directory and shell.
- Observe that the new chat works correctly and reports:
/mnt/d/Projects/PFOS
bash
Affected session ID:
019fbee1-4ad9-75d0-8c6e-8b610eaf4799
What is the expected behavior?
Changing the Codex execution environment should not silently break existing chats.
Codex should detect that existing chats contain environment-specific Windows metadata and provide a supported migration workflow.
The migration should:
- Map Windows paths to their WSL equivalents, for example:
D:\Projects\EOE
->
/mnt/d/Projects/EOE
- Replace the saved PowerShell environment with the appropriate WSL shell.
- Regenerate workspace-root, sandbox, and permission-profile records using the current WSL schema.
- Allow the user to select or confirm the destination Codex project and working directory.
- Preserve the complete conversation history, tool results, accumulated context, title, and project placement.
- Validate the migrated chat before committing the change.
- Create a backup and provide rollback if migration fails.
- Warn the user before changing execution environments when existing chats contain incompatible environment-specific state.
Moving a chat into another project should also provide an option to rebind the chat's working directory and execution environment to that project.
Additional information
The affected local rollout JSONL file was inspected.
Results:
- Total JSONL records: 171
- Valid JSON records: 171
- Invalid JSON records: 0
- Conversation content appears intact
- Nine records contain Windows environment or path settings
- Codex reported seven parsing errors while attempting to resume or fork the session under WSL
Examples of retained Windows-specific state include:
- session_meta.payload.cwd = D:\Projects\EOE
- saved shell = powershell
- workspace roots under D:\Projects\EOE
- Windows-specific permission-profile entries
- Windows-specific .git, .agents, and .codex paths
This indicates an execution-environment schema compatibility problem rather than corrupted conversation data.
The environment switch disrupted an active multi-project workflow for more than two hours and required manual investigation of:
- project bindings
- chat continuation behavior
- working-directory state
- local SQLite state
- rollout JSONL records
- permission-profile records
- possible manual recovery procedures
Long-running Codex chats contain substantial project decisions, history, tool output, and accumulated working context. Abandoning those chats and starting over is not an acceptable migration strategy.
A first-class Windows-native to WSL migration and rollback tool is needed.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This is not a duplicate of #36098: that's a feature request for per-project environment selection, this is a migration bug for chats created before the switch.
----
The following description of this issue on my machine is from the Claude session that resolved the issue. The repro and facts have been verified unless stated otherwise.
----
Confirming on a second setup, with a root cause and a migration that works.
Codex desktop MSIX
26.803.5235.0, Windows 10.0.26200, WSL2 Ubuntu,[desktop] runCodexInWindowsSubsystemForLinux = true. Protocol probes againstcodex-cli 0.145.0.Root cause
The app stores per-thread paths in Windows form and replays them to the app-server. Under WSL
C:\...isn't POSIX-absolute, and the outcome depends on the field's type:| Field | Type | Result |
|---|---|---|
|
runtimeWorkspaceRoots(thread/start,thread/resume,turn/start) |AbsolutePathBuf|Invalid request: AbsolutePathBuf deserialized without a base path||
cwd| plainstring| silently joined onto the app-server's process cwd |Threads created after the switch get translated paths and are fine; only pre-existing ones break.
The second row explains the malformed paths in the OP — backslashes are legal filename characters on Linux, so the whole path becomes one relative segment. Running the app-server from a known directory:
In the app that base is the read-only MSIX resources directory, hence the
…/app/resources/C:\Users\...paths.Repro
Two things will otherwise waste your time:
runtimeWorkspaceRootsneeds theexperimentalApicapability, and the server exits at stdin EOF — hold stdin open or you only see the first response.C:\...→-32600 AbsolutePathBuf deserialized without a base path./mnt/c/...→ success. UNC\\wsl$\<distro>\...→ same error. Same onturn/start, which is why a thread can open and then fail only on send: with a deliberately bogusthreadId, the Windows path dies at deserialization while the POSIX path gets as far asthread not found.Workaround: migrate the stored state
All in
%USERPROFILE%\.codex\.codex-global-state.json. Close the app first — it flushes on exit and will overwrite your edit. TranslateC:\x→/mnt/c/xand\\wsl$\<distro>\x→/x, strip\\?\and\\?\UNC\, then dedupe (mixed-separator variants of one root collapse into it):thread-writable-roots— what triggers the errorthread-project-assignments.<id>.cwd— needed too, or the error clears and threads resume into the phantom directory abovethread-workspace-root-hints,thread-projectless-output-directories— same, for projectless threadsLeave
local-projects,electron-saved-workspace-roots,active-workspace-rootsandelectron-workspace-root-labelsin Windows form. Working threads coexist with those, which is what shows the app translates per request rather than storing POSIX.39 entries across 20 threads here, and the previously-broken chats now reopen and continue with history intact. Presumably one-directional: switching back to Windows-native should break migrated threads the same way in reverse, though I haven't tested that.
Suggested fix
Apply the translation you already do for new threads when replaying stored thread state. And consider typing
cwdasAbsolutePathBuf— as a plain string it silently yields the phantom directory instead of a clear error.Likely the same defect as #16815 / #29454 / #23209 / #23213; #20014 is the same thing in
plugin/list.This Windows-native → WSL case is a strong persisted-schema/path migration test. I’m field-testing
codex-rescue==0.1.0a4against durable session metadata that remains parseable but becomes incompatible with a new execution environment.If the original affected rollout still exists, could you run:
pipx install codex-rescue==0.1.0a4codex-rescue doctor --json "/path/to/the-affected-rollout.jsonl"The command is read-only. It won’t rewrite Windows paths or migrate the Desktop environment, but it can show whether the persisted transcript is structurally healthy and which diagnostic class the retained state falls into.
A sanitized findings/status summary is enough. Please don’t publish the raw rollout, databases, prompts, tool data, credentials, repository names, session IDs, or private paths.