Bug: Codex Desktop fails after enabling WSL

Open 💬 3 comments Opened May 21, 2026 by Jafa7
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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?

  1. Delete or rename the existing Codex home directory:

C:\Users\<user>\.codex

  1. Start Codex Desktop on Windows.
  1. Let Codex complete initial startup/onboarding.
  1. Codex creates:

C:\Users\<user>\.codex\state_5.sqlite

  1. Enable WSL mode in Codex Desktop settings.
  1. Restart Codex Desktop.
  1. Codex attempts to start the runtime under:

/mnt/c/Users/<user>/.codex

  1. 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.sqlite before 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.sqlite contains migration 1 checksum:

54BBD6F4...

  • WSL/Linux-created state_5.sqlite contains 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.

codex-wsl-sqlite-migration-analysis-en.md

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #23923
  • #23893
  • #23841
  • #23777
  • #23913

Powered by Codex Action

gugia · 3 months ago

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. for codex-rs/state/migrations/0001_threads.sql:

  • Windows/CRLF checksum: 54BBD6F4...
  • WSL/Linux/LF checksum: 627EF191...

So a Windows-created CODEX_HOME/state_5.sqlite fails when opened by the WSL app-server.

Suggested fix:

  1. Pin all state migration SQL files to LF in .gitattributes:
# Keep sqlx migration checksums stable across Windows and WSL/Linux builds.
codex-rs/state/migrations/*.sql text eol=lf
codex-rs/state/logs_migrations/*.sql text eol=lf
codex-rs/state/goals_migrations/*.sql text eol=lf

goals_migrations should be included too, since current main has goals_1.sqlite.

  1. Add a runtime repair step before migrator.run(...).

In the shared SQLite open path, before running the SQLx migrator:

  • check whether _sqlx_migrations exists;
  • read successful applied migrations and their stored checksums;
  • for each embedded migration, if the stored checksum differs from the current checksum, compute the LF and CRLF variants of that migration SQL;
  • if the stored checksum matches only a line-ending-equivalent variant, update _sqlx_migrations.checksum to the current embedded checksum;
  • otherwise leave it alone and let SQLx still fail with VersionMismatch.

This keeps real migration drift protected while allowing safe repair for line-ending-only drift.

Tests I would expect:

  • a DB with a CRLF checksum opens successfully under an LF build and rewrites the checksum;
  • a DB with an arbitrary invalid checksum still fails;
  • ideally this is covered through the common open path so state_5.sqlite, logs_2.sqlite, and goals_1.sqlite are 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.

xdifu · 3 months ago

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:

git clone https://github.com/xdifu/codex-repair.git
cd codex-repair
python codex-repair.py fix --apply

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/*.jsonl read-only.