Skip to content

Regression: Windows Desktop + WSL shell stays poisoned after reboot; live app-server holds deleted CODEX_HOME/tmp/arg0 helper path despite unified_exec=false #25317

Open

Description

@MisterRound

Summary

This is a regression / worse state than the already-reported Windows Desktop + WSL shell failures in #22185 and #16970.

In other words, reboot/relaunch is no longer a reliable recovery for this failure class.

Environment

  • Windows Desktop package: OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0
  • Desktop release string in logs: 26.527.31326
  • Electron runtime: 42.1.0
  • Active WSL app-server / hashed WSL agent: codex-cli 0.135.0-alpha.1
  • Stable WSL agent path still present: codex-cli 0.130.0-alpha.5
  • Platform: Windows 11 + WSL2 Ubuntu
  • WSL kernel observed: 6.6.114.1-microsoft-standard-WSL2
  • Desktop CODEX_HOME: %USERPROFILE%\.codex, seen from WSL as /mnt/c/Users/<user>/.codex
  • Shell in the affected Desktop session: /bin/bash
  • unified_exec=false in both:
    • %USERPROFILE%\.codex\config.toml
    • <wsl-home>/.codex/config.toml

Actual Behavior

Normal shell/tool calls fail before the requested command starts:

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

The workspace path is not the problem. The active session's PATH contains a stale helper directory:

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

That directory no longer exists:

stat: cannot statx '/mnt/c/Users/<user>/.codex/tmp/arg0/codex-arg0UXHjoV': No such file or directory

However, the live WSL app-server still holds an fd to the stale helper lock path:

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

And fdinfo shows the live process still has a POSIX advisory write lock on that old lock inode:

lock: 1: POSIX  ADVISORY  WRITE <app-server-pid> ...

Later, a new codex-arg0* directory can appear under the same tmp/arg0 root with valid Linux symlinks:

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

But this does not repair the active thread, because the active thread/app-server state remains pinned to the deleted codex-arg0UXHjoV helper path.

Why This Is Not Just a Duplicate

This is related to #16970 and #22185, but it is not the same recovery state:

  • unified_exec=false is already applied in every relevant config.
  • A full OS reboot was attempted more than once.
  • The failure still reappears in the current Desktop build family.
  • The live app-server can retain an fd/lock for a helper path that is already gone from the filesystem.
  • Creating a newer helper directory does not rebind the active shell/tool runtime.

So the old practical workaround, "restart/reboot Desktop so a fresh helper dir is created," is no longer sufficient.

Source-Level Findings

I checked current origin/main of openai/codex at:

8acaec73b6a227ae9375064e910ecf86f2620ec0

Relevant current behavior in codex-rs/arg0/src/lib.rs:

  • The helper root is shared under find_codex_home()/tmp/arg0.
  • Unix creates helper symlinks in that root: apply_patch, applypatch, codex-execve-wrapper, codex-linux-sandbox.
  • Windows creates .bat helper shims in the same root.
  • Cleanup is lock-only: janitor_cleanup() attempts to lock each child dir and deletes it if locking succeeds.

This is fragile in Windows Desktop + WSL because the Desktop home is shared across a Windows process family and a WSL/Linux process family, and in this setup CODEX_HOME is on DrvFS under /mnt/c.

PR #17570 adds a .pid owner sentinel and appears to address the Linux-side stale-helper case, but I do not see that commit on origin/main. Also, as currently written on that branch, the owner PID liveness check returns false on non-Linux. That means it may not fully protect a WSL-owned helper directory if a Windows-native Codex process is janitoring the same shared %USERPROFILE%\.codex\tmp\arg0 tree.

Related Runtime Evidence

The same Desktop logs show mixed runtime surfaces in the same launch:

stdio_transport_spawned ... executablePath=%USERPROFILE%\.codex\bin\wsl\<hash>\codex ... spawnCommand=wsl.exe
Current reported app-server version: currentVersion=0.135.0-alpha.1

But Browser/Computer Use runtime selection in the same session selected Windows-native paths:

browser_use_runtime_paths_selected codexCliPath=%LOCALAPPDATA%\OpenAI\Codex\bin\<hash>\codex.exe ... platform=win32
computer-use native pipe startup failed ... "Windows Computer Use helper paths are unavailable"

I am not claiming the Browser/Computer Use plugin failure is the root cause of the shell failure. I am including it because it shows the same Desktop session crossing Windows-native and WSL-native runtime/cache surfaces while sharing the same Codex home.

Expected Behavior

For Windows Desktop + WSL sessions:

  • unified_exec=false should remain a reliable mitigation for the Windows CreateProcess(/bin/bash) failure class.
  • Reboot/relaunch should not deterministically return to a poisoned helper state.
  • A live app-server should not have its active tmp/arg0 helper directory deleted while it still uses paths inside it.
  • If a cached codex-linux-sandbox / arg0 helper path returns ENOENT, the runtime should rehydrate/rebind helper paths instead of leaving the thread permanently broken.

Suggested Fix Direction

One or more of:

  1. Namespace arg0 helper dirs by runtime family/platform/distro, for example separate Windows-native helpers from WSL/Linux helpers instead of sharing CODEX_HOME/tmp/arg0.
  2. Add a helper manifest containing platform, helper kind, owner PID, and WSL distro/runtime identity; janitors should only clean dirs from their own runtime family.
  3. Make the active-helper ownership check cross-runtime safe. If a Windows process cannot verify a WSL PID, it should not treat that helper dir as safe to delete.
  4. On ENOENT for cached codex_linux_sandbox_exe / arg0 helper paths, rebind once from the live app-server's current helper guard or recreate a helper dir, then retry.
  5. Add a Windows Desktop + WSL release-gate test with:
    • CODEX_HOME on %USERPROFILE%\.codex / /mnt/c/Users/<user>/.codex
    • unified_exec=false
    • WSL app-server active
    • repeated Desktop restarts/reboots or workspace/thread switches
    • verification that shell calls still run and PATH does not point at a deleted codex-arg0* dir.

Related Issues / PRs

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
    tool-callsIssues related to tool calling
    on May 30, 2026
  2. github-actions commented on May 30, 2026

    @github-actions
    Contributor

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

    Powered by Codex Action

  3. MisterRound commented on May 30, 2026

    @MisterRound
    Author

    I reviewed the duplicate bot suggestion, #25280. It is related and probably the closest existing report, but I do not think this issue should be closed as a straight duplicate.

    The difference I am trying to isolate here is the regression state and live ownership evidence:

    • This repro is specifically after the older mitigation is already in place: unified_exec=false in both Windows and WSL configs.
    • Full reboot/relaunch was already attempted multiple times, so this is worse than the original "restart regenerates a good helper dir" state from Unified exec caches stale ~/.codex/tmp/arg0 session path and fails with ENOENT until app restart #16970.
    • The live WSL app-server still has an fd to the deleted helper dir's .lock path, and fdinfo shows a POSIX advisory write lock owned by that live app-server pid.
    • Later/newer codex-arg0* helper dirs can exist, but the active thread remains pinned to the deleted helper path.

    #25280 is broader: it also tracks elevated Windows sandbox setup/refresh failures and Windows-local repo sandbox behavior. This issue is intended to be the narrower WSL/Desktop arg0 lifecycle regression with the fd/lock evidence and the "reboot no longer recovers" behavior.

  4. MisterRound commented on May 30, 2026

    @MisterRound
    Author

    Additional live workaround/root-cause isolation from the same affected session.

    I tested a non-destructive live rehydrate of the exact stale helper path referenced by PATH:

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

    Steps used, sanitized:

    1. Recreate the exact missing codex-arg0* directory.
    2. Recreate .lock.
    3. Add Linux symlinks:
    apply_patch -> /mnt/c/Users/<user>/.codex/bin/wsl/<hash>/codex
    applypatch -> /mnt/c/Users/<user>/.codex/bin/wsl/<hash>/codex
    codex-execve-wrapper -> /mnt/c/Users/<user>/.codex/bin/wsl/<hash>/codex
    codex-linux-sandbox -> /mnt/c/Users/<user>/.codex/bin/wsl/<hash>/codex
    

    Result: normal non-escalated shell calls recovered in the same active thread. pwd, uname -a, and command -v codex-linux-sandbox succeeded. apply_patch also recovered and successfully edited a probe file.

    Two important extra findings:

    1. WSL/DrvFS can get into an inconsistent recreate state for the deleted helper path. stat and Windows PowerShell Get-Item report the helper path missing, but WSL mkdir() returns EEXIST. Creating the directory from Windows PowerShell with New-Item -ItemType Directory works around that state; then WSL can add symlinks once the path becomes visible.

    2. Running the Windows-native bundled codex.exe after the rehydrate deletes the repaired WSL helper directory and breaks the active WSL shell again. A new Windows .bat helper dir appears under the same shared CODEX_HOME/tmp/arg0 root. Holding a WSL flock on the recreated .lock did not protect the directory from the Windows-native cleanup path.

    That makes the mixed-runtime root cause much more concrete: a Windows-native Codex process and a WSL/Linux Codex app-server share the same %USERPROFILE%/.codex/tmp/arg0 namespace. The Windows-native arg0 janitor can delete the WSL helper dir that the live WSL app-server/thread still has cached, and WSL advisory locking does not reliably protect it.

    This also changes the workaround guidance:

    • Rehydrating the exact stale helper dir can recover the current thread temporarily.
    • It is not durable if Windows-native Codex/plugin/browser-use paths run afterward.
    • The durable product fix needs platform/runtime namespacing or a janitor rule that never deletes helper dirs from another runtime family.
  5. MisterRound commented on May 30, 2026

    @MisterRound
    Author

    One more workaround test result: holding the repaired helper dir open from WSL does not prevent the Windows-native cleanup.

    I tried two protection variants after rehydrating the exact stale WSL helper dir:

    1. Start a long-running WSL process holding an exclusive flock on the repaired .lock file.
    2. Start a long-running WSL process with its current working directory inside the repaired codex-arg0* helper dir.

    Then I invoked the Windows-native bundled codex.exe again.

    Result: in both cases, the repaired WSL helper dir was later deleted and a new Windows .bat helper dir appeared under the same shared CODEX_HOME/tmp/arg0 root. Normal WSL shell/tool calls broke again.

    So this is not just "WSL did not hold the right lock." Handle-based local protection from WSL is not a reliable workaround against the Windows-native arg0 cleanup path. The practical local workaround is only to rehydrate after the break, and then avoid triggering Windows-native Codex/plugin/browser-use paths. The product fix needs to stop Windows and WSL runtimes from janitoring each other's helper dirs in the first place.

  6. poroburu commented on Jun 3, 2026

    @poroburu

    I supplied a workaround script in #25799 based upon your diagnosis. It is not durable and needs to be run every Codex session.

  7. kosei-w90607 commented on Jun 6, 2026

    @kosei-w90607

    Adding another sanitized reproduction that appears to match this Desktop + WSL failure family.

    Setup:

    • Windows 11 + WSL2
    • Codex App settings:
      • Default open location: WSL
      • Agent environment: Windows Subsystem for Linux
      • Integrated terminal shell: WSL
    • WSL distro: Ubuntu-22.04
    • Workspace: WSL-hosted git repository under /home/<user>/Projects/<repo>
    • WSL login shell: /home/linuxbrew/.linuxbrew/bin/zsh (Homebrew zsh)
    • Direct WSL terminal can resolve the shell and bash:
      • echo "$SHELL" -> /home/linuxbrew/.linuxbrew/bin/zsh
      • getent passwd "$USER" ends with /home/linuxbrew/.linuxbrew/bin/zsh
      • command -v zsh -> /home/linuxbrew/.linuxbrew/bin/zsh
      • /home/linuxbrew/.linuxbrew/bin/zsh is a symlink to ../Cellar/zsh/5.9/bin/zsh
      • command -v bash -> /usr/bin/bash
    • Relevant config currently observed:
      • approval_policy = "untrusted"
      • sandbox_mode = "workspace-write"

    Symptoms from Codex App:

    • exec_command stops before the requested command reaches WSL.
    • The default shell /home/linuxbrew/.linuxbrew/bin/zsh is reported as not found.
    • /bin/bash and /usr/bin/bash are reported as No such file or directory.
    • PTY execution fails because codex-linux-sandbox is not present at a temporary helper path.
    • Node-side attempt to spawn wsl.exe returns EPERM.
    • The app terminal snapshot still shows a WSL cwd and git branch, but requested command output such as pwd, echo "$SHELL", or git status --short --branch was not obtained because execution fails before the command starts.

    This makes it look less like a repository or WSL shell configuration issue and more like the Desktop WSL command runner / sandbox helper failing before entering WSL. The direct WSL shell is healthy, including Homebrew zsh and /usr/bin/bash.

    Update after further testing:

    • wsl.exe -d Ubuntu-22.04 --cd /home/<user>/Projects/<repo> --exec pwd succeeds and returns the expected WSL repo path.
    • wsl.exe ... --exec sh -lc 'echo "$SHELL"' succeeds and returns /home/linuxbrew/.linuxbrew/bin/zsh.
    • wsl.exe ... --exec git status --short --branch succeeds and shows the expected branch/worktree state.
    • Normal Codex Desktop shell execution still fails before reaching WSL because it appears to try launching the WSL shell path from the Windows side, effectively a Windows-native CreateProcess("/home/linuxbrew/.linuxbrew/bin/zsh", ...) style failure.

    So the WSL distro, repo, git, and Linuxbrew zsh are healthy when invoked through explicit wsl.exe --exec. The failing path appears to be the Desktop normal exec path selecting or falling back to a Windows-native process launch for a Linux shell path instead of wrapping the shell command through WSL.

    One caveat: a Git status signal from Desktop should not necessarily be treated as proof that normal shell execution is healthy. Git/repository status may be coming from a Desktop/plugin/MCP/internal repository metadata path rather than the same exec_command path that tries to launch the shell.

  8. MisterRound commented on Jun 10, 2026

    @MisterRound
    Author

    Follow-up with the latest sanitized local findings from the same Windows Desktop + WSL investigation.

    The original diagnosis still holds, but the current reproduction is sharper: this is a mixed-runtime arg0 lifecycle problem, not a missing repo/shell/bwrap problem.

    Current locally proven behavior:

    • A WSL-backed Desktop app-server can be pinned to a helper path like:
    %USERPROFILE%\.codex\tmp\arg0\codex-arg0<hash>
    
    • When that exact helper dir disappears, shell/tool calls fail before the requested command starts:
    Io(Os { code: 2, kind: NotFound, message: "No such file or directory" })
    
    • Recreating the exact stale helper dir with Linux symlinks restores the live thread temporarily:
    apply_patch -> %USERPROFILE%\.codex\bin\wsl\<hash>\codex
    applypatch -> %USERPROFILE%\.codex\bin\wsl\<hash>\codex
    codex-execve-wrapper -> %USERPROFILE%\.codex\bin\wsl\<hash>\codex
    codex-linux-sandbox -> %USERPROFILE%\.codex\bin\wsl\<hash>\codex
    
    • The local recovery script now preserves an existing .lock, can recover from WSL/DrvFS oddities where WSL mkdir() reports EEXIST while stat/Windows APIs report the path missing, and can fall back to the live app-server lock fd when visible.

    The additional finding is that Computer Use/browser-use sidecars can make this worse:

    • Product-generated Windows-native node_repl.exe -> codex.exe app-server --listen stdio:// sidecars can run with shared CODEX_HOME=%USERPROFILE%\.codex.
    • Those Windows-native sidecars create .bat arg0 helpers under the same shared %USERPROFILE%\.codex\tmp\arg0 root.
    • When that happens in a WSL-backed Desktop session, shared-root Windows .bat helpers and WSL/Linux symlink helpers are in the same janitor namespace.
    • Cleanup/recovery that only creates a new helper dir is not durable if the active app-server remains pinned to the deleted helper path or if another runtime family can janitor the shared root again.

    Current source/PR reading still suggests the durable fix should be one or both of:

    1. Runtime-family helper namespacing, e.g. tmp/arg0/windows/... and tmp/arg0/wsl/<distro>/..., with janitors sweeping only their own family.
    2. A helper manifest with runtime family, owner PID namespace, creator executable, helper kind (bat vs symlink), and a safe cross-runtime cleanup rule.
    3. A one-shot rehydrate/rebind-on-ENOENT path for cached helper executable paths before surfacing shell failure.

    Local acceptance gate until upstream fixes this:

    • shared %USERPROFILE%\.codex\tmp\arg0 contains only WSL/Linux helper dirs during WSL app-server sessions;
    • Windows .bat helpers are allowed only in an isolated Windows runtime home, not the shared Desktop home;
    • no bare/shared-home node_repl.exe -> codex.exe app-server --listen stdio:// sidecar chains are live;
    • if pre-exec ENOENT happens, rehydrate the exact stale helper dir before trying /bin/bash -lc, repo-path checks, or bwrap debugging.

    This is also why #26985 looks directionally right: moving runtime-heavy WSL temp/cache state out of the shared Windows-backed home and/or namespacing arg0 by runtime family directly addresses the cross-runtime janitor collision.

  9. rpc1990 commented on Aug 18, 2026

    @rpc1990

    Additional cross-platform confirmation: this is reproducible in a native Linux VS Code Remote environment, not only Windows Desktop + WSL.

    Environment

    • VS Code Remote extension: openai.chatgpt-26.810.41047-linux-x64
    • Bundled runtime: codex-cli 0.148.0-alpha.9
    • Platform: Linux x86_64
    • CODEX_HOME resolves to a GPFS filesystem
    • Affected path class: $CODEX_HOME/tmp/arg0/codex-arg0*

    Observed twice on 2026-08-17

    The same failure occurred in two successive VS Code Codex execution hosts.

    Occurrence 1

    • Last confirmed managed-sandbox success: 2026-08-17T16:19:02Z
    • First host-wide failures: 2026-08-17T16:19:08Z
    • The live app server still referenced codex-arg03UKYsn, but that directory was absent.
    • App-server FD 3 pointed to .../codex-arg03UKYsn/.lock (deleted).
    • /bin/bash, /bin/sh, /usr/bin/bash, and /usr/bin/sh all failed before the requested command started:
      Failed to create unified exec process: No such file or directory (os error 2)
    • A fresh standalone sandbox using the same bundled Codex binary passed.

    Reloading the remote extension host created a new helper directory and temporarily restored managed execution.

    Occurrence 2

    • First logged failure: 2026-08-17T23:10:05Z
    • The replacement app server remained alive, but its new helper directory codex-arg02wA5kG was also absent.
    • App-server FD 3 again pointed to .../codex-arg02wA5kG/.lock (deleted).
    • fdinfo showed that the live app server still held an advisory write FLOCK on the deleted inode.
    • Even a minimal managed pwd failed with the same unified-exec ENOENT.
    • Execution outside the affected managed sandbox remained healthy.

    This recurrence after the extension-host reload is strong evidence that the issue is not limited to stale state inherited from one old process. It also broadens the affected environment beyond the Windows/WSL shared-home case: an active native-Linux app server on GPFS can lose its own helper directory while retaining the deleted lock inode.

    The deletion actor is still unknown. No evidence implicated the shell binaries, cwd, project, Bubblewrap, user namespaces, or process/file-descriptor exhaustion.

    A robust fix likely needs both:

    1. cleanup protection that does not treat an active helper directory as unused when filesystem locking/liveness evidence is unreliable; and
    2. one-time helper rehydration/rebinding when a cached arg0 helper path returns ENOENT.

    I preserved bounded redacted excerpts and source hashes locally. Raw session transcripts and logs are not attached because they contain private conversation and project data, but I can provide additional sanitized diagnostics or use a secure upload channel if maintainers request them.

  10. kosei-w90607 commented on Aug 31, 2026

    @kosei-w90607

    Follow-up: switching an existing Windows project to WSL corrupts cwd and rejects no-op saves

    I reproduced two additional Windows Desktop / WSL transition failures on a current build. They may share a host/path mapping cause, but they are distinct user-visible failures.

    Environment

    • Windows Desktop package: OpenAI.Codex_26.825.6671.0_x64__2p2nqsd0c76g0
    • Windows 11 + WSL2
    • Distribution name: Ubuntu-22.04 (userspace upgraded in place to Ubuntu 24.04.4 LTS)
    • The existing project was originally registered from a Windows path containing non-ASCII components: D:\ユーザー<user>\Documents\Project\asmr-library

    A. Switching the existing Windows-backed task to WSL corrupts cwd/execution state

    1. Start with the existing Windows-backed project/task.

    2. Switch the Codex App execution environment to WSL.

    3. The task context reports a malformed cwd that combines a WindowsApps resource prefix with an unconverted raw Windows path:

      /mnt/c/Program Files/WindowsApps/OpenAI.Codex_26.825.6671.0_x64__2p2nqsd0c76g0/app/resources/D:\ユーザー<user>\Documents\Project\asmr-library

    4. Every shell choice fails before the requested command starts: the default shell, /bin/bash, /usr/bin/bash, and /home/linuxbrew/.linuxbrew/bin/zsh all return:

      Failed to create unified exec process: No such file or directory (os error 2)

    5. A same-directory fork of the task fails in exactly the same pre-exec state, so a fresh conversation/fork does not recover it.

    6. This is not a WSL installation or shell problem. From a healthy Windows-hosted task, explicit wsl.exe execution succeeds; /bin/bash, /usr/bin/bash, Linuxbrew zsh, and WSL-native repositories are accessible.

    7. Switch the App setting back to Windows. The task remains poisoned and reports another malformed cwd:

      D:\Program Files\WindowsApps\OpenAI.Codex_26.825.6671.0_x64__2p2nqsd0c76g0\app\ユーザー<user>\Documents\Project\asmr-library

    8. Default PowerShell execution then fails with:

      CreateProcessWithLogonW failed: 267

    9. Supplying the original correct Windows path explicitly as workdir makes PowerShell work again. No repository, Git, shell, or Codex config files were changed during this reproduction.

    This suggests that changing the execution host does not reinitialize or validate the task/project cwd, and switching back does not restore it.

    B. A Windows-created project rejects even an unchanged save while WSL is selected

    With WSL selected, open the settings/edit UI for an existing project that was created while the App was using Windows. Press Save without changing any field. The App still returns an error and refuses the save.

    Therefore this is not specifically a bad renamed value or a name-validation failure: a no-op save of the existing Windows-created project is rejected. In practice, any edit becomes impossible while WSL is selected. I observed this at the UI level; I did not instrument the internal save request/response.

    This may indicate that saving revalidates or rewrites the stored Windows host/path metadata through the currently selected WSL environment and rejects the unchanged Windows value.

    Expected behavior

    • If converting an existing Windows-backed project/task to WSL is supported, the App should remap or reinitialize the cwd to a valid Linux path and create a fresh WSL executor/app-server state.
    • Switching back to Windows should restore a valid Windows cwd rather than preserving a hybrid WindowsApps-prefixed path.
    • A no-op save must not fail solely because the selected execution environment differs from the environment in which the project was created.
    • If cross-host switching or cross-host editing is intentionally unsupported, the UI should block it before mutation and explain that a separate WSL-native project must be added. It should not poison the task or present an editable form whose unchanged values cannot be saved.

    The current OpenAI WSL documentation says that Codex runs inside Linux when WSL2 is selected and that terminals should show Linux paths such as /home/...; the hybrid cwd above violates that invariant.

  11. brian-p-ray commented on Sep 30, 2026

    @brian-p-ray

    I reproduced this on September 30, 2026 with:

    • Windows Codex package: 26.928.2636.0
    • WSL app-server: 0.159.2
    • WSL: 3.0.1.0
    • Ubuntu, WSL 2
    • Shared Codex home: /mnt/c/Users/<user>/.codex

    Normal sandboxed exec_command calls failed in existing and new chats, across two workspace paths, with:

    Failed to create unified exec process:
    No such file or directory (os error 2)
    

    Direct WSL commands worked. Both /usr/bin/bwrap and a user-local Bubblewrap copy reported version 0.6.1 and successfully created a basic sandbox. Running pwd through Codex outside the sandbox also succeeded.

    The live WSL app-server’s PATH referenced:

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

    That directory was missing, while the app-server still held an open file descriptor pointing to its .lock. The versioned Codex executable remained present.

    Both WSL filesystem checks and Windows PowerShell Get-Item reported the helper directory missing. Attempting to recreate it from WSL failed with EEXIST.

    Recovery succeeded by renaming the empty tmp/arg0 parent directory to a backup, recreating the parent and the exact session directory expected by the live backend, and restoring these four symlinks to the live backend’s existing Codex executable:

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

    After that repair, normal sandboxed pwd succeeded in both workspaces without restarting the backend or changing sandbox permissions.

    Desktop startup logs also contained bundled_executable_relocation_failed for codex-resources/bwrap, with ENOENT during stat_source. We have not established that this warning caused the command-launch failure.

    This confirms that restoring the missing helper paths recovered sandboxed execution in this session. It does not identify which process removed them or prove that the WSL update caused the deletion. The repair has not yet been validated across another restart.

  12. akikettu commented on Oct 10, 2026

    @akikettu

    Additional confirmation: ProcMon deletion evidence and working ext4 bind-mount workaround (October 10, 2026)

    I reproduced this issue on a newer Codex Desktop build and captured additional evidence using Linux strace and Windows Sysinternals Process Monitor.

    Environment

    • Windows Codex Desktop: 26.1007.2314.0

    • Desktop WSL runtime: codex-cli 0.162.0-alpha.17.2

    • WSL2: Debian 13, kernel 6.18.33.2-microsoft-standard-WSL2

    • HOME=/home/<user>

    • CODEX_HOME=/mnt/c/Users/<user>/.codex

    • Bubblewrap 0.12.0, independently verified working

    1. Confirmed failing syscall

    The WSL app-server attempts to execute its sandbox helper:

    execve("/mnt/c/Users/<user>/.codex/tmp/arg0/codex-arg0<id>/codex-linux-sandbox", ...)
        = -1 ENOENT
    exit_group(127)

    The active WSL app-server still holds file descriptor 3 pointing to the missing helper directory's .lock file.

    The helper directory is not visible to either WSL stat or Windows PowerShell, while attempting to recreate it from WSL returns EEXIST.

    2. Windows ProcMon captured helper deletion

    ProcMon captured Windows-native codex.exe explicitly deleting a codex-linux-sandbox reparse point and its containing helper directory.

    Representative operations:

    codex.exe  SetDispositionInformationEx
    ...\codex-linux-sandbox
    SUCCESS
    Flags: FILE_DISPOSITION_DELETE, FILE_DISPOSITION_POSIX_SEMANTICS
    

    codex.exe SetDispositionInformationEx
    ...\codex-arg0<id>
    SUCCESS
    Flags: FILE_DISPOSITION_DELETE, FILE_DISPOSITION_POSIX_SEMANTICS

    The deleting executable belonged to the Desktop installation and was running an exec-server --remote command. Another observed Windows process created Linux helper symlinks successfully using FSCTL_SET_REPARSE_POINT.

    The ProcMon directory IDs were not correlated one-to-one with the earlier strace session, but these traces independently confirm both the sandbox execution failure and Windows-native cleanup of Linux helper files.

    3. Verified workaround: isolate WSL's arg0 using an ext4 bind mount

    With Codex Desktop closed, run in WSL:

    SRC="$HOME/.codex/tmp/arg0"
    DST="/mnt/c/Users/<user>/.codex/tmp/arg0"

    sudo mount --bind "$SRC" "$DST"
    findmnt --mountpoint "$DST"

    Then launch Codex Desktop.

    The mount makes WSL processes see the Linux ext4 helper directory at the Windows-backed CODEX_HOME/tmp/arg0 path, while Windows-native processes continue to see the original Windows directory.

    Actual A/B test results:

    Sequence Normal sandbox execution
    Launch Desktop without bind mount FAIL: ENOENT
    Add bind mount while Desktop is running Still FAIL
    Close Desktop, unmount, remount, then launch Desktop PASS
    Run /bin/sh -c 'echo SANDBOX_TEST_OK' PASS, exit 0
    Run pwd and read the WSL repository directory PASS, exit 0

    All successful commands used the normal sandbox without elevated permissions.

    This suggests that separating the Windows-native and WSL helper-directory namespaces resolves the observed failure, provided the separation is in place before Desktop's WSL app-server initializes. Adding the mount after the app-server has initialized does not repair the affected session.

    This is a workaround, not a recommended permanent product configuration. It supports the proposed upstream fix of separating arg0 namespaces by runtime/platform and preventing cross-runtime cleanup.

    I can provide sanitized ProcMon and strace excerpts if useful.

  13. akonyer commented on Oct 10, 2026

    @akonyer

    I'm seeing this too with NixOS on WSL3, using Codex Desktop on Windows.

    Setup:

    • Codex Desktop: 26.1007.2314.0 (just updated).
    • WSL software version: 3.0.1.0; distribution runs as WSL2.
    • Desktop agent environment: WSL.
    • Native Linux app-server, with CODEX_HOME=/mnt/c/Users/<user>/.codex supplied by Desktop.
    • CODEX_SQLITE_HOME=/home/<user>/.codex/sqlite.

    We initially found a custom Windows user environment override, CODEX_CLI_PATH=codex, which made Desktop use an npm-installed Linux CLI (0.159.3). We removed that override and restarted Desktop. The failure reproduced with Desktop's bundled Linux executable, so it is not limited to that older npm installation. The running executable was under .codex/bin/wsl/d04c9d9044dd4815/codex; its SHA-256 matched the Linux executable shipped in the Desktop package.

    After the restart:

    1. A new tmp/arg0/codex-arg0f4TNOy directory existed with .lock, apply_patch, applypatch, codex-execve-wrapper, and codex-linux-sandbox.
    2. That directory subsequently disappeared while the native Linux app-server remained running.
    3. The backend still held its POSIX advisory write lock on fd 3.
    4. In a WSL project conversation, uname -s, pwd, and git branch --show-current all failed before execution with No such file or directory (OS error 2), using normal sandbox permissions and no PowerShell or wsl.exe fallback.

    There are no Windows user or machine CODEX_HOME overrides. Desktop's default shared-home behavior has been left unchanged. No bind-mount workaround is installed.

    We have not identified the deleting process on this machine, so this is confirmation of the missing-helper failure on NixOS WSL, rather than independent proof of the cleanup process responsible. Updating Desktop and restarting with its bundled Linux runtime did not resolve it.

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 workingtool-callsIssues related to tool callingwindows-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