Skip to content

Windows Desktop: switching Agent environment to WSL2 fails startup with state db backfill handshake timeout #36320

Open

Description

@xiaodream551-a11y

What version of the Codex App are you using (From “About Codex” dialog)?

  • MSIX package: OpenAI.Codex_26.727.4816.0_x64
  • Desktop build observed in logs / MCP env: 26.727.40816 / package 26.727.4816.0
  • WSL-side CLI available: codex-cli 0.146.0

What subscription do you have?

ChatGPT Pro (desktop signed in)

What platform is your computer?

  • Windows 11 25H2, build 26200, x64
  • WSL2 distro: Ubuntu-24.04 (default, Running)
  • WSL kernel: 6.18.33.2-microsoft-standard-WSL2
  • Windows user: Lenovo
  • WSL user: xdreamer (/home/xdreamer)

What issue are you seeing?

After changing Settings → Agent environment from Windows native to WSL2 / Windows Subsystem for Linux, Codex Desktop fails to start and shows:

ChatGPT failed to start.
Codex app-server initialize handshake timed out

Desktop logs show the app-server is launched inside WSL, then blocks on a state DB backfill from the Windows Codex home mounted at /mnt/c/..., and the Desktop 30s initialize handshake times out.

Sanitized Desktop log excerpt:

[wsl] eligible distro list listResult="NAME            STATE           VERSION\n* Ubuntu-24.04    Running         2"
[spawn-async] Spawning process inside WSL
[StdioConnection] stdio_transport_spawned
  executablePath=C:\Users\<user>\.codex\bin\wsl\<hash>\codex
  spawnCommand=wsl.exe
[AppServerConnection] Transport start success transport=stdio
[AppServerConnection] Initialize handshake still pending
  connectionError={"code":"connection-failed","message":"state db backfill is running at /mnt/c/Users/<user>/.codex; waiting up to 30s before retrying startup initialization"}
  durationMs=30011
initialize_handshake_result outcome=failure
  errorMessage="Codex app-server initialize handshake timed out"
app_server_connection.closed code=1
  reason="Error: failed to initialize sqlite state runtime under /home/<wsl-user>/.codex/sqlite: timed out waiting for state db backfill at /mnt/c/Users/<user>/.codex after 30s (status: running)"
Desktop bootstrap failed to start the main app phase=bootstrap-import-main

Important recovery detail:

  • %USERPROFILE%\.codex\.codex-global-state.json had "runCodexInWindowsSubsystemForLinux": false
  • but %USERPROFILE%\.codex\config.toml still had:
[desktop]
runCodexInWindowsSubsystemForLinux = true

Desktop continued spawning WSL until config.toml was set to false. After that:

stdio_transport_spawned executablePath=...\WindowsApps\OpenAI.Codex_...\app\resources\codex.exe
initialize_handshake_result durationMs=225 outcome=success

So WSL mode left the app unlaunchable, and the dual config sources made recovery non-obvious.

What steps can reproduce the bug?

  1. Use Codex Desktop on Windows with an existing local profile under %USERPROFILE%\.codex.
  2. Ensure WSL2 is installed with a default Ubuntu distro that is eligible (wsl -l -v shows Running / Stopped version 2).
  3. Open Codex Desktop in Windows native mode (works).
  4. Go to Settings and switch Agent environment to WSL / Windows Subsystem for Linux.
  5. Quit and relaunch Codex Desktop.
  6. Observe the fatal dialog:
    Codex app-server initialize handshake timed out
  7. Inspect Desktop logs and observe WSL spawn + 30s state db backfill timeout from /mnt/c/Users/<user>/.codex into /home/<wsl-user>/.codex/sqlite.
  8. Set [desktop] runCodexInWindowsSubsystemForLinux = false in %USERPROFILE%\.codex\config.toml and relaunch.
  9. Observe Windows-native codex.exe spawn and a successful handshake in a few hundred ms.

Local size context (not multi-GB session history)

At failure time, approximate sizes under %USERPROFILE%\.codex:

logs_2.sqlite       ~438 MB
logs_2.sqlite-wal   ~14 MB
state_5.sqlite      ~1.7 MB
sessions            ~645 MB (127 files)
archived_sessions   ~103 MB (137 files)

This is much smaller than the multi-tens-of-GiB history case in #35674, but still enough for WSL-mode startup backfill over /mnt/c to exceed the fixed 30s Desktop handshake budget.

There was also a non-fatal warning while launching WSL mode:

bundled_executable_relocation_failed
executableName=bwrap
sourcePath=...\app\resources\codex-resources\bwrap
ENOENT

That appears secondary; the fatal path is the state db backfill timeout.

What is the expected behavior?

  1. Switching Agent environment to WSL2 should either:
    • complete first-run / state backfill successfully, or
    • open the app with a progress/recovery UI instead of a fatal handshake timeout.
  2. State DB backfill / SQLite init performed over /mnt/c should not be on a hard 30s critical path that prevents Desktop bootstrap.
  3. If WSL mode fails, Desktop should provide a one-click fallback to Windows native mode without requiring manual edits of config files.
  4. runCodexInWindowsSubsystemForLinux should have a single source of truth. Having .codex-global-state.json say false while config.toml [desktop] still says true (and Desktop obeys the latter) makes recovery confusing when the app cannot open Settings.
  5. Diagnostic logs / DB maintenance should not block app launch; if backfill is required, it should be resumable and backgrounded.

Additional information

Related issues (same failure family, different emphasis):

This report is specifically about:

  1. Agent environment → WSL2 as the trigger
  2. Desktop spawning WSL app-server
  3. fatal state db backfill ... after 30s during initialize handshake
  4. dual config sources (config.toml vs .codex-global-state.json) complicating recovery

Workaround that restored launch on this machine:

# %USERPROFILE%\.codex\config.toml
[desktop]
runCodexInWindowsSubsystemForLinux = false

I can provide additional sanitized Desktop log excerpts if useful. I am not attaching raw session JSONL / auth / full SQLite dumps because they contain local paths and conversation content.

Activity

  1. added
    bugSomething isn't working
    appIssues related to the Codex desktop app
    windows-osIssues related to Codex on Windows systems
    app-serverIssues involving app server protocol or interfaces
    on Jul 31, 2026
  2. github-actions commented on Jul 31, 2026

    @github-actions
    Contributor

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

    Powered by Codex Action

  3. anghel4d commented on Aug 3, 2026

    @anghel4d

    Additional reproduction on NixOS WSL2, with a non-destructive recovery

    I reproduced this on a current Desktop build with NixOS as the WSL2 distribution. This adds two useful findings:

    1. NixOS and the WSL launch itself were healthy; the synchronous state backfill exceeded Desktop's fixed 30-second initialize deadline.
    2. On this build, the backfill continued after Desktop reported bootstrap failure. Letting it finish and then relaunching repaired WSL mode without deleting or moving any user data.

    Environment

    • Codex Desktop package: OpenAI.Codex_26.727.6591.0_x64
    • WSL-side app-server: 0.146.0-alpha.9.2
    • Windows 11 Pro x64, build 26200
    • WSL2 kernel: 6.18.33.2-microsoft-standard-WSL2
    • Distribution: NixOS 26.11.20260729.0954f7e

    What happened

    The Desktop successfully discovered NixOS and spawned the relocated Linux binary through wsl.exe:

    [StdioConnection] stdio_transport_spawned ... spawnCommand=wsl.exe
    [AppServerConnection] Transport start success ... transport=stdio
    

    The actual WSL process was alive with valid stdin/stdout pipes, a valid working directory, the expected HOME, and the intended split state paths:

    CODEX_HOME=/mnt/c/Users/<user>/.codex
    CODEX_SQLITE_HOME=/home/<user>/.codex/sqlite
    

    At exactly 30 seconds, Desktop failed the bootstrap:

    Initialize handshake still pending ... durationMs=30011
    initialize_handshake_result durationMs=30012
    errorMessage="Codex app-server initialize handshake timed out"
    outcome=failure
    Desktop bootstrap failed to start the main app
    

    However, the app-server process remained alive and continued building:

    /home/<user>/.codex/sqlite/state_5.sqlite
    

    The source Windows state_5.sqlite was approximately 125.2 MB. During the failed launch, the WSL-local database grew continuously to approximately 122.8 MB plus its WAL. At about 69 seconds after spawn, its backfill_state changed to:

    status = complete
    

    It contained:

    • 1,128 threads, matching the Windows state DB
    • 99 thread spawn edges, matching the Windows state DB
    • 44 applied SQLx migrations
    • PRAGMA quick_check(1) = ok

    The transport stopped shortly after the backfill reached complete.

    Non-destructive recovery observed

    I then relaunched Desktop without changing configuration, deleting data, reinstalling, or shutting down WSL. The same WSL backend initialized successfully:

    initialize_handshake_result durationMs=2826 outcome=success
    Codex CLI initialized
    app_server_connection.state_changed ... next=connected
    window ready-to-show
    

    For a profile of this size, the effective workaround was therefore:

    1. Start Desktop in WSL mode.
    2. After the 30-second failure, leave the process alone long enough for the first WSL state backfill to finish (roughly another 40 seconds in this case).
    3. Close/relaunch Desktop.
    4. Subsequent WSL initialization completes within the handshake budget.

    This is much safer than deleting SQLite state or moving session history, although it may not work for very large profiles if Desktop terminates the backfill before it can complete.

    NixOS and bwrap findings

    The preliminary suspicion that this was a NixOS launch/shell problem was ruled out:

    • WSL startup was fast.
    • /usr/bin/bash worked.
    • The relocated Codex binary launched and handled app-server requests.
    • The successful second launch used the same command and environment.

    Desktop also logged the known warning that its packaged codex-resources/bwrap was absent. NixOS supplied /run/current-system/sw/bin/bwrap, and the second launch succeeded despite the same relocation warning, so that warning was not causal here.

    Suggested fix

    The state migration/backfill should not share a fatal 30-second deadline with the app-server protocol handshake. Possible approaches:

    • complete or resume the migration before starting the handshake deadline;
    • expose a migration-progress/heartbeat state and keep Desktop open with progress UI;
    • allow the app-server to initialize while historical backfill proceeds asynchronously;
    • reconnect automatically when a still-running backfill reaches complete; or
    • at minimum, present a safe “wait and relaunch” recovery action instead of a generic fatal startup error.

    The key evidence here is that the supposedly failed app-server was healthy and made measurable progress, and the exact same backend initialized in 2.826 seconds once its one-time WSL-local backfill had completed.

  4. xlr1012514182 commented on Aug 9, 2026

    @xlr1012514182

    nice issue!

  5. T-Higgins commented on Aug 27, 2026

    @T-Higgins

    Having this issue too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appapp-serverIssues involving app server protocol or interfacesbugSomething isn't workingperformancewindows-osIssues related to Codex on Windows systems

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions