Bug: Codex Desktop fails after enabling WSL
What version of the Codex App are you using (From “About Codex” dialog)?
26.519.22136
What subscription do you have?
Plus
What platform is your computer?
Microsoft Windows NT 10.0.26200.0 x64
What issue are you seeing?
After enabling WSL mode in Codex Desktop and restarting the app, Codex fails to start because it cannot access its local SQLite database.
Full error message with PII redacted:
Codex cannot access its local database.
The app cannot finish launching until its SQLite database is accessible.
Database path: Path unavailable in app-server startup error
Error: (code=1, signal=null).
Most recent error: Error: failed to initialize sqlite state runtime under
/mnt/c/Users/<user>/.codex: failed to initialize state runtime at
/mnt/c/Users/<user>/.codex: migration 1 was previously applied but has been modified
I did a preliminary investigation and found that the SQLite database itself does not appear to be corrupted. PRAGMA integrity_check returns ok.
The issue appears to be a SQLx migration checksum mismatch between the Windows Codex runtime and the WSL/Linux Codex runtime while sharing the same CODEX_HOME.
<img width="691" height="364" alt="Image" src="https://github.com/user-attachments/assets/b1d724ad-c152-41a6-a325-bc2df0de3873" />
What steps can reproduce the bug?
- Delete or rename the existing Codex home directory:
C:\Users\<user>\.codex
- Start Codex Desktop on Windows.
- Let Codex complete initial startup/onboarding.
- Codex creates:
C:\Users\<user>\.codex\state_5.sqlite
- Enable WSL mode in Codex Desktop settings.
- Restart Codex Desktop.
- Codex attempts to start the runtime under:
/mnt/c/Users/<user>/.codex
- Startup fails with:
migration 1 was previously applied but has been modified
No code snippet is required to reproduce this; it is caused by the Desktop + WSL runtime initialization flow.
Session id / token usage / context window usage: not applicable.
What is the expected behavior?
After enabling WSL mode and restarting Codex Desktop, the app should start normally.
Codex should either:
- use migration files with identical checksums across Windows and WSL builds;
- avoid creating a Windows-initialized
state_5.sqlitebefore switching to WSL; - use a separate WSL-compatible state database/CODEX_HOME;
- or provide a safe migration/repair path when switching from Windows runtime to WSL runtime.
A newly initialized Codex home should not become unusable immediately after enabling WSL mode.
Additional information
I performed a preliminary investigation and can attach a detailed Markdown report.
Key findings:
- The SQLite databases pass
PRAGMA integrity_check = ok. - The failure is in SQLx migration validation, not SQLite corruption.
- Windows-created
state_5.sqlitecontains migration 1 checksum:
54BBD6F4...
- WSL/Linux-created
state_5.sqlitecontains migration 1 checksum:
627EF191...
- The embedded migration SQL in the Windows binary appears to use CRLF line endings (
\r\n). - The embedded migration SQL in the WSL/Linux binary appears to use LF line endings (
\n). - SQLx appears to hash the raw migration bytes, so the same logical migration gets different checksums across runtimes.
- The WSL runtime then opens the Windows-created database from:
/mnt/c/Users/<user>/.codex
and fails because the checksum stored in _sqlx_migrations does not match the WSL runtime’s embedded migration checksum.
This looks like a cross-runtime migration checksum incompatibility combined with shared state path and Windows-first initialization order.
3 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I think the fix should be two-part: prevent new drift, and repair existing databases that already contain the opposite line-ending checksum.
Root cause appears to be that
sqlx::migrate!hashes the raw migration SQL embedded at compile time. On Windows checkouts, these files may be CRLF in the working tree, while WSL/Linux builds embed LF. This produces different SQLx checksums for the same logical migration, e.g. forcodex-rs/state/migrations/0001_threads.sql:54BBD6F4...627EF191...So a Windows-created
CODEX_HOME/state_5.sqlitefails when opened by the WSL app-server.Suggested fix:
.gitattributes:goals_migrationsshould be included too, since currentmainhasgoals_1.sqlite.migrator.run(...).In the shared SQLite open path, before running the SQLx migrator:
_sqlx_migrationsexists;_sqlx_migrations.checksumto the current embedded checksum;VersionMismatch.This keeps real migration drift protected while allowing safe repair for line-ending-only drift.
Tests I would expect:
state_5.sqlite,logs_2.sqlite, andgoals_1.sqliteare all protected.This should let Desktop switch between Windows and WSL runtimes while sharing the same
CODEX_HOME, without requiring users to delete or rename.codex.This is the same root-cause family as #23777 / #23787: the WSL/Linux Codex backend rejects a Windows-created SQLite DB because SQLx migration checksums differ at the CRLF-vs-LF byte level. Moving
state_5.sqlite*/logs_2.sqlite*aside is a launch workaround, but it forces Codex to rebuild metadata instead of repairing the existing DBs.For users who want to preserve local history metadata, I published a non-destructive repair tool: https://github.com/xdifu/codex-repair
Windows PowerShell / Windows Terminal:
If you run it from WSL bash to repair Windows Codex Desktop data, pass
--codex-home "/mnt/c/Users/<WindowsUser>/.codex"so it does not target WSL's own~/.codex.It backs up the SQLite DBs, extracts the active backend's expected checksums, schema-verifies before rewriting
_sqlx_migrations, and leaves~/.codex/sessions/*.jsonlread-only.