Windows Desktop + WSL workspace: unified_exec tries to CreateProcess /bin/bash and fails with ENOENT

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

What version of Codex is running?

Codex Desktop / CLI observed in local diagnostics:

  • codex-cli 0.130.0-alpha.5
  • Windows 11 host
  • WSL2 Ubuntu workspace

What subscription do you have?

Pro

Which model were you using?

GPT-5.5

What platform is your computer?

Hybrid Windows Desktop + WSL2 setup:

  • WSL distro: Ubuntu
  • WSL kernel observed in smoke test: Linux BOOK-*** 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun 5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

What issue are you seeing?

In Codex Desktop with a WSL-backed workspace, normal shell/tool calls can fail before the command starts when [features].unified_exec = true.

The failing tool call tries to launch a Linux shell path directly through the Windows-backed process creation path:

/bin/bash -lc ...

The observed error from normal Codex tool calls is:

CreateProcess { message: "Rejected(\"Failed to create unified exec process: No such file or directory (os error 2)\")" }

This is misleading because /bin/bash exists and works in WSL. The failure appears to be that the Windows-side unified exec runner is attempting to CreateProcess a WSL/Linux absolute path instead of routing it through WSL.

Steps to reproduce

Local repro conditions:

  1. Use Codex Desktop on Windows 11.
  2. Open a WSL-backed workspace under /mnt/c/....
  3. Configure Codex with:
[features]
unified_exec = true
shell_snapshot = true
  1. Start a session where the shell is WSL bash and the workspace path is /mnt/c/....
  2. Run a normal shell/tool command such as pwd, uname -a, or ls -l /bin/bash /usr/bin/bash.

Observed in the active thread:

exec_command failed for `/bin/bash -lc pwd`: CreateProcess { message: "Rejected(\"Failed to create unified exec process: No such file or directory (os error 2)\")" }

The same failure occurred for:

/bin/bash -lc 'uname -a'
/bin/bash -lc 'ls -l /bin/bash /usr/bin/bash'

Expected behavior

In a WSL-backed Codex Desktop workspace, if Codex chooses /bin/bash -lc ..., it should launch it in WSL, not as a native Windows executable path.

Alternatively, Codex should detect this unsupported hybrid mode and either:

  • automatically avoid unified exec for Windows Desktop + WSL shell/workspace sessions, or
  • return a clear diagnostic explaining that unified exec cannot directly launch WSL absolute paths from the Windows process runner.

Actual behavior

Normal shell/tool calls fail before command start with os error 2, even though WSL and /bin/bash are healthy.

Read-only checks from a Windows-backed Node runtime showed:

where wsl.exe
C:\Windows\System32\wsl.exe
C:\Users\**\AppData\Local\Microsoft\WindowsApps\wsl.exe
wsl.exe -e /bin/bash -lc 'printf "shell=%s user=%s cwd=%s\n" "$SHELL" "$(id -un)" "$PWD"; ls -l /bin/bash /usr/bin/bash'

Output:

shell=/bin/bash user=doug cwd=/mnt/c/Users/**/OneDrive/Documents/New project
-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /bin/bash
-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /usr/bin/bash

Direct Windows-side spawn of /bin/bash reproduced the lower-level problem:

spawn /bin/bash ENOENT

codex sandbox windows /bin/bash -lc pwd also reproduced the same class of issue:

windows sandbox failed: CreateProcessAsUserW failed: 2

Workaround

Set:

[features]
unified_exec = false
shell_snapshot = true

Then restart Codex Desktop.

After disabling unified_exec, fresh low-reasoning codex exec smoke tests passed.

Smoke 1:

codex exec -c model_reasoning_effort='low' -C '/mnt/c/Users/**/OneDrive/Documents/New project' 'Run exactly this smoke test: execute pwd with the shell tool, then report the raw command output and whether the shell tool started successfully. Do not edit files.'

Result:

/mnt/c/Users/**/OneDrive/Documents/New project

Smoke 2:

codex exec -c model_reasoning_effort='low' -C '/mnt/c/Users/**/OneDrive/Documents/New project' 'Run exactly this smoke test with the shell tool: ls -l /bin/bash /usr/bin/bash && uname -a. Report the raw command output and whether the shell tool started successfully. Do not edit files.'

Result:

-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /bin/bash
-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /usr/bin/bash
Linux BOOK-8S5UL4MRV3 6.6.87.2-microsoft-standard-WSL2 #1 SMP PREEMPT_DYNAMIC Thu Jun  5 18:30:46 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux

Why this looks like a Codex/runtime bug

Source inspection suggests unified_exec changes shell tool selection and routes execution through the unified PTY-backed path. In this hybrid environment, the Windows-side runtime can receive a Linux argv (/bin/bash -lc ...) and attempt to create it as a Windows process.

Relevant source areas inspected:

  • codex-rs/features/src/lib.rs
  • unified_exec is stable, and defaults to !cfg!(windows).
  • This suggests native Windows normally avoids unified exec unless explicitly enabled.
  • codex-rs/tools/src/tool_config.rs
  • When Feature::UnifiedExec is enabled and ConPTY is supported, tool config can select ConfigShellToolType::UnifiedExec.
  • When disabled, it falls back away from unified exec.
  • codex-rs/core/src/tools/handlers/unified_exec/exec_command.rs
  • exec_command builds the command using the session shell and delegates through UnifiedExecProcessManager.
  • codex-rs/core/src/tools/runtimes/unified_exec.rs
  • Unified exec builds sandbox/process execution metadata and delegates process startup.
  • codex-rs/core/src/unified_exec/process_manager.rs
  • The Windows path can ultimately spawn via Windows sandbox/process/PTY machinery, which cannot directly resolve /bin/bash.

Related issues

This looks related but not identical to:

  • #16970: Windows + WSL2 unified exec ENOENT involving stale ~/.codex/tmp/arg0/.../codex-linux-sandbox paths.
  • #17240: unified exec/tool path instability causing Failed to create unified exec process: No such file or directory (os error 2).
  • #14367: Windows unified exec sandbox behavior; not the same root cause, but related to unified exec edge cases on Windows.

Suggested fixes

One of:

  1. Detect Windows Desktop + WSL-backed shell/workspace sessions and route unified exec process startup through wsl.exe when the argv is a WSL/Linux path.
  2. Automatically disable/refuse unified exec for this hybrid mode until WSL path routing is supported.
  3. Improve diagnostics when Windows unified exec receives a Linux absolute path such as /bin/bash, so users see a clear message instead of generic os error 2.

Additional notes

This setup is Windows Desktop, but the agent workspace and shell are WSL2 Ubuntu. Treating it as purely native Windows is misleading: the intended command environment is Linux, but the process creation boundary appears to be Windows-side when unified exec is enabled.

View original on GitHub ↗

12 Comments

github-actions[bot] contributor · 2 months ago

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

  • #21147
  • #20770

Powered by Codex Action

MisterRound · 2 months ago

Additional sanitized finding from local debugging: in Windows Desktop + WSL mode, the desktop app and the WSL app-server can read different config homes. In this case the visible Windows config had , but the WSL app-server was still reading the WSL user's , where , which reactivated this failure mode. Filed separately as #22759 because it appears to be a distinct config-home / app-server bug that can cause #22185 to reappear unexpectedly.

MisterRound · 2 months ago

Additional sanitized finding from local debugging: in Windows Desktop + WSL mode, the desktop app and the WSL app-server can read different config homes. In this case the visible Windows config had unified_exec = false, but the WSL app-server was still reading the WSL user's ~/.codex/config.toml, where unified_exec = true, which reactivated this failure mode.

Filed separately as #22759 because it appears to be a distinct config-home / app-server bug that can cause #22185 to reappear unexpectedly.

MisterRound · 2 months ago

Follow-up RCA from the same Windows Desktop + WSL environment. unified_exec=false is still the necessary mitigation, but I also hit a related stale arg0 helper failure that can look like the same shell-runner problem.

Environment:

  • Codex Desktop package: OpenAI.Codex_26.506.3741.0_x64__2p2nqsd0c76g0
  • WSL: 2.7.3.0, kernel 6.6.114.1-1, Windows 10.0.26200.8457
  • WSL app-server binary: /mnt/c/Users/<user>/.codex/bin/wsl/codex
  • Codex CLI: codex-cli 0.130.0-alpha.5
  • Both Windows and WSL configs now have [features] unified_exec = false.

Failure signature before reboot:

execution error: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })

Important detail: the workspace path was not missing. The failing thread's PATH contained a stale helper directory:

/mnt/c/Users/<user>/.codex/tmp/arg0/codex-arg0i3QOLP

That directory had existed earlier with Linux helpers:

apply_patch
applypatch
codex-execve-wrapper
codex-linux-sandbox

Later it was gone, while newer helper dirs existed under the same tmp/arg0 root but contained only Windows .bat shims:

apply_patch.bat
applypatch.bat

A full Windows/Codex reboot cleared it. After reboot, the live PATH helper dir existed again and contained Linux symlinks to the WSL app-server binary:

apply_patch -> /mnt/c/Users/<user>/.codex/bin/wsl/codex
applypatch -> /mnt/c/Users/<user>/.codex/bin/wsl/codex
codex-execve-wrapper -> /mnt/c/Users/<user>/.codex/bin/wsl/codex
codex-linux-sandbox -> /mnt/c/Users/<user>/.codex/bin/wsl/codex

This connects the unified_exec WSL launch issue with the stale arg0 helper class tracked in #16970. Practical local recovery is full Desktop/app-server restart; recreating the deleted helper directory is the wrong fix because it hides a runtime mismatch.

MisterRound · 1 month ago

Follow-up from the same Windows Desktop + WSL environment: this failure has regressed into a worse state than the original unified_exec=true report here.

The current repro is not unified_exec=true:

  • unified_exec=false is set in both %USERPROFILE%\.codex\config.toml and <wsl-home>/.codex/config.toml.
  • The machine was fully rebooted more than once.
  • The current Desktop build family is OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0, with WSL app-server codex-cli 0.135.0-alpha.1.
  • Normal shell/tool calls still fail before command execution with:
execution error: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })

The current evidence points at the tmp/arg0 helper lifecycle rather than the old CreateProcess(/bin/bash) path:

PATH contains:
/mnt/c/Users/<user>/.codex/tmp/arg0/codex-arg0UXHjoV

stat:
No such file or directory

/proc/<app-server-pid>/fd/3:
/mnt/c/Users/<user>/.codex/tmp/arg0/codex-arg0UXHjoV/.lock

fdinfo:
POSIX ADVISORY WRITE lock owned by the live app-server pid

So the active WSL app-server can still hold a lock fd to a helper dir that is gone from the filesystem, and the active thread remains pinned to that deleted helper path. New helper dirs may be created later, but they do not repair the already-poisoned thread/app-server state.

I opened a focused follow-up issue for the regression here: https://github.com/openai/codex/issues/25317

Relationship to this issue:

  • This issue remains the right place for the original unified_exec=true / Windows CreateProcess(/bin/bash) failure.
  • The new issue is for the post-workaround regression where unified_exec=false and reboot are no longer enough because the shared CODEX_HOME/tmp/arg0 helper state can still poison shell execution.
chisong1 · 1 month ago

I’m hitting this same class of failure on Windows Desktop + WSL.

Environment:

  • Codex Desktop for Windows, Agent environment = Windows Subsystem for Linux
  • Integrated terminal shell = WSL
  • Repo lives under /home/user/project
  • WSL has /usr/bin/bash
  • WSL Codex CLI is installed: codex-cli 0.132.0
  • bubblewrap 0.9.0 is installed

Observed:

  • Normal exec_command calls fail before command execution with:

CreateProcess { message: "Rejected(\"Failed to create unified exec process: No such file or directory (os error 2)\")" }

  • Retrying the same WSL command with escalated execution succeeds.
  • The running WSL app-server process is:

/mnt/c/Users/user/.codex/bin/wsl/.../codex app-server --analytics-default-enabled

This makes the Desktop WSL agent mode unreliable for normal coding work even though the WSL environment itself is healthy.

ChenWenBrian · 1 month ago

same issue, codex desktop version 26.602.30954
it can't work with wsl now.

hyman-ren · 1 month ago

Codex Desktop 26.602.3474.0 on Windows + WSL cannot start any shell command.

Even a shell builtin test like type -a codex fails before execution with:
execution error: Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })

My WSL Ubuntu24 is healthy and /bin/bash, /bin/sh exist. This indicates the Desktop WSL Agent / unified_exec layer is failing before command execution.

afonseca08 · 1 month ago

I’m seeing the same failure signature in Codex Desktop with a WSL-backed workspace.

Environment:

  • Codex Desktop app Version 26.602.40724
  • Windows 10 host with WSL enabled
  • Agent environment appears to be WSL/Linux
  • Workspace is inside WSL, under the Linux filesystem, not a Windows drive path
  • Shell configured as bash
  • Filesystem sandbox mode shown to the agent: workspace-write

Observed behavior:

A basic shell command fails before the command starts:

exec_command failed for `/bin/bash -lc 'pwd
which bash
ls -la'`: CreateProcess { message: "Rejected(\"Failed to create unified exec process: No such file or directory (os error 2)\")" }
JaimeLanders · 1 month ago

I'm also hitting this issue as well, codex said my evidence might be helpful so pasting it below:

Your evidence is useful because you reproduce it on newer build 26.602.40724, while the identical VS Code WSL test passes.

I’d add this comment rather than open a duplicate:

Still reproducible on Codex Windows Desktop build `26.602.40724`.

Configuration:

```toml
[desktop]
runCodexInWindowsSubsystemForLinux = true
integratedTerminalShell = "powershell"

WSL environment:

  • Arch Linux on WSL2
  • Bash 5.3.9
  • Git 2.53.0
  • User <SNIPPED>, uid 1000
  • Repository stored under /home/...

Codex Desktop result:

Bash: FAIL. $SHELL=/usr/bin/bash, but launcher reports path not found.
Git: PASS.
Pipes: BLOCKED by Bash launcher failure.
Parallel commands: PASS.
WSL identity: PASS.

Representative error:

exec_command failed for `/usr/bin/bash -lc ...`:
CreateProcess {
  message: "Rejected(\"Failed to create unified exec process:
  No such file or directory (os error 2)\")"
}

Changing integratedTerminalShell from wsl to powershell, fully
restarting Codex Desktop, and starting a new thread did not help.

The same smoke test passes completely in the Codex VS Code extension
running in a WSL: Arch remote window. Bash, Git, pipes, pipefail,
parallel commands, repository detection, and WSL identity all work there.

This isolates the failure to the Windows Desktop-to-WSL command launcher,
rather than Bash, .bashrc, Git, or the WSL installation.

jgilfoil · 1 month ago

I’m seeing this same issue on current Codex Desktop, and the documented workaround did not resolve it.

Environment:

  • Codex Desktop package: OpenAI.Codex_26.602.4764.0_x64__2p2nqsd0c76g0
  • Agent environment: Windows Subsystem for Linux
  • Integrated terminal shell: WSL
  • WSL distro: Ubuntu
  • Workspace: /home/jason/repos/projects/trading-harness-v2
  • WSL kernel: Linux Prometheus 5.15.167.4-microsoft-standard-WSL2
  • Bundled WSL Codex binaries observed:
  • /mnt/c/Users/jason/.codex/bin/wsl/codex -> codex-cli 0.130.0-alpha.5
  • /mnt/c/Users/jason/.codex/bin/wsl/81645c5d269e0fb2/codex -> codex-cli 0.137.0-alpha.4

Repro in a fresh Codex Desktop session:

pwd && uname -a && command -v bash && ls -l /bin/bash /usr/bin/bash

Sandboxed result:

exec_command failed for `/bin/bash -lc 'pwd && uname -a && command -v bash && ls -l /bin/bash /usr/bin/bash'`: CreateProcess { message: "Rejected(\"Failed to create unified exec process: No such file or directory (os error 2)\")" }

Running the exact same command with escalation/full access succeeds:

/home/jason/repos/projects/trading-harness-v2
Linux Prometheus 5.15.167.4-microsoft-standard-WSL2 #1 SMP Tue Nov 5 00:21:55 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
/usr/bin/bash
-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /bin/bash
-rwxr-xr-x 1 root root 1446024 Mar 31  2024 /usr/bin/bash

Things I tried that did not fix it:

  • Restarted Codex Desktop
  • Started a fresh session
  • Ran wsl --shutdown
  • Rebooted Windows host
  • Added the workaround to both config files:
  • C:\Users\jason\.codex\config.toml
  • /home/jason/.codex/config.toml
[features]
unified_exec = false
shell_snapshot = true
  • Confirmed no project-level .codex/config.toml override exists
  • Renamed C:\Users\jason\.codex\tmp
  • No /home/jason/.codex/tmp existed
  • Renamed C:\Users\jason\.codex\bin\wsl to force Codex Desktop to rebuild the WSL bin cache

After all of that, the behavior is unchanged: sandboxed WSL exec fails before launching /bin/bash, while escalated/full-access exec works inside WSL.

This looks like the sandboxed WSL exec bridge is still trying to create /bin/bash from the wrong side of the Windows/WSL boundary, or otherwise not entering WSL before process creation.

hoklims · 15 days ago

Adding a Desktop-free repro and separating the three failures now stacked on this thread, so each one gets its own fix. Thanks @MisterRound; your source inspection matches what I traced.

Repro without Desktop. The Windows sandbox spawn reproduces straight from the CLI:

$ codex sandbox windows /bin/bash -lc pwd
windows sandbox failed: runner error: CreateProcessAsUserW failed: 2

/bin/bash is a valid WSL path but not a Windows executable, so the Windows-side process create fails with error 2. The Desktop tool-call failures reported above (Failed to create unified exec process: No such file or directory (os error 2)) are the same class from the sibling pipe/PTY path. Both hit the same wall; the source trace below covers both.

Three distinct causes are stacked here. They want three homes:

| Cause | Trigger | Signature | Belongs in |
|---|---|---|---|
| Windows runner spawns /bin/bash natively | unified_exec = true (or codex sandbox windows) | fails at start; unified_exec=false clears it in-session | this issue |
| Stale CODEX_HOME/tmp/arg0 helper + live lock fd | survives unified_exec=false and reboot | Io(Os code:2); PATH points at a deleted arg0 dir held by an app-server lock | #25317 |
| Config-home split across the WSL boundary | Desktop reads Windows ~/.codex, app-server reads WSL ~/.codex | the two configs disagree on unified_exec | #22759 |

Commenters split across these: cause 1 for chisong1 and afonseca08; cause 2 for jgilfoil, who exhausted the workarounds and still fails; a cause 3 signal from JaimeLanders. Scoping #22185 to cause 1 and moving the post-workaround Io(Os code:2) reports to #25317 unblocks a clean fix for each.

Cause 1, where it spawns (main @ be33f80bc65159c094ecd06bf155afa3061ce23d). open_session_with_prepared_exec_env in codex-rs/core/src/unified_exec/process_manager.rs:955 has two Windows spawn paths, and neither routes through WSL:

  • pipe/pty (the Desktop tool-call failure): request.command.split_first() at l.1075 hands program/args to codex_utils_pty::pipe::spawn_process_no_stdin_with_inherited_fds at l.1091 (or pty::spawn_process_with_inherited_fds at l.1080 for tty), which reaches tokio::process::Command::new(program).spawn() in codex-rs/utils/pty/src/pipe.rs. /bin/bash resolves as a native Windows exe, returns os error 2, and gets wrapped into UnifiedExecError::create_process at l.1102.
  • sandbox (the codex sandbox windows repro above): SandboxType::WindowsRestrictedToken at l.966 goes to CreateProcessAsUserW in codex-rs/windows-sandbox-rs/src/process.rs, wrapped at l.1045/1062, which is the CreateProcessAsUserW failed: 2 variant.

The file has no wsl anywhere, and wsl.exe has zero matches repo-wide. The one ForeignPath guard (errors.rs) covers the cwd at l.972 and l.1071, never the program argv.

Fix for cause 1: at the split (l.1078), detect a WSL-backed session (a Linux-absolute program, or an explicit WSL flag) and spawn wsl.exe -e <program> <args> instead of the raw argv; put the same guard ahead of the sandbox branch at l.966. Smaller version: extend the cwd-only ForeignPath check to cover program, so the failure is a clear diagnostic instead of os error 2.

I can put up a repro-backed patch for cause 1 in a fork if that helps.