Windows Desktop remote-control listener can stay on stale cached binary missing sandbox helper
Codex Windows remote-control listener can stay on stale cached binary missing sandbox helper
Summary
On Windows Codex Desktop, mobile/remote-triggered commands stopped reaching the active Windows session reliably after an update/restart cycle. Local Codex Desktop shell execution worked after restart, but commands initiated from mobile still failed or only appeared after restarting Codex Desktop.
Root cause in this environment was a stale remote-control app-server process still listening on 127.0.0.1:14567 from an older cached Codex binary directory. That stale cache directory contained codex.exe only and did not contain codex-windows-sandbox-setup.exe or codex-command-runner.exe.
As a result, remote-triggered shell commands hit:
setup refresh: failed to spawn codex-windows-sandbox-setup.exe: program not found
Restarting only the listener from the newest complete cached Codex binary fixed mobile -> Windows command execution.
Environment
- OS: Windows 11 x64
- Codex Desktop package observed:
OpenAI.Codex_26.527.3686.0_x64__2p2nqsd0c76g0 - Working cached CLI:
codex-cli 0.135.0-alpha.1 - Current config workaround already set:
[windows]
sandbox = "unelevated"
Observed stale state
The remote-control listener was still bound to an older cached binary:
127.0.0.1:14567 -> C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\958d608b5e0546a5\codex.exe
CommandLine: codex.exe app-server --listen ws://127.0.0.1:14567 --enable remote_control --analytics-default-enabled
That directory contained:
codex.exe
It did not contain:
codex-windows-sandbox-setup.exe
codex-command-runner.exe
The current complete cache directory contained all required files:
C:\Users\<user>\AppData\Local\OpenAI\Codex\bin\7dea4a003bc76627\
codex.exe
codex-windows-sandbox-setup.exe
codex-command-runner.exe
Relevant sandbox log
From %USERPROFILE%\.codex\.sandbox\sandbox.log:
START: C:\Program Files (x86)\PowerShell\7\pwsh.exe -NoProfile -Command ...
setup refresh: spawning codex-windows-sandbox-setup.exe (cwd=..., payload_len=...)
setup refresh: failed to spawn codex-windows-sandbox-setup.exe: program not found
Workaround that fixed it
- Find the remote-control listener:
Get-NetTCPConnection -LocalPort 14567 -State Listen |
Select-Object LocalAddress,LocalPort,State,OwningProcess
- Inspect the owning process:
Get-CimInstance Win32_Process -Filter "ProcessId=<pid>" |
Select-Object ProcessId,ExecutablePath,CommandLine
- If it points to an incomplete/stale cache dir, stop that listener process and restart it from the newest complete cached binary:
Stop-Process -Id <pid> -Force
Start-Process `
-FilePath "$env:LOCALAPPDATA\OpenAI\Codex\bin\7dea4a003bc76627\codex.exe" `
-ArgumentList @(
'app-server',
'--listen',
'ws://127.0.0.1:14567',
'--enable',
'remote_control',
'--analytics-default-enabled'
) `
-WindowStyle Hidden
After this, mobile-triggered commands reached the Windows Codex session again and shell/SCP tests succeeded.
Suggested product-side fixes
- On Desktop startup/update, ensure the
14567remote-control listener is not left running from an older cached binary. - Before using a cached binary directory for
app-server --enable remote_control, verify that the directory also containscodex-windows-sandbox-setup.exeandcodex-command-runner.exe. - If
setup refreshlogsprogram not found, include the resolved app-server executable path and expected helper path in the user-facing diagnostic. - Add this to
codex doctor: detect a remote-control listener running from a stale/incomplete cached binary.
Related but separate finding
This machine also previously hit setup refresh failures when TEMP/TMP resolved to a system temp junction. The stale listener issue above remained visible after local shell execution was fixed, so it appears to be a separate remote-control/update-cache problem.
5 Comments
Follow-up after more validation on the same machine:
After restarting the remote-control listener from the complete
7dea4a003bc76627cache directory, a command initiated from mobile reached the Windows Codex session immediately and successfully executed a PowerShell directory listing.I also validated the previously failing SCP path from a mobile-initiated Codex command. One detail that may be relevant for diagnostics: inside the sandboxed PATH,
where scp/where sshfirst returned.sbx-denybin\scp.batand.sbx-denybin\ssh.bat, then the real bundled OpenSSH binaries. Calling the real binaries explicitly worked:The real transfer test copied a small file from Windows to a Linux host via SCP, verified it via SSH, and removed it again successfully.
So in this environment the remote/mobile failure was fixed by replacing the stale
14567listener process; the SCP issue was then only a PATH/sandbox-wrapper confusion during testing, not a remaining network or auth problem.For local prevention I added a small diagnostic helper that checks:
127.0.0.1:14567codex.exe,codex-windows-sandbox-setup.exe, andcodex-command-runner.exeThis reinforces the suggested product-side fix: Desktop startup/update should validate the remote-control listener's executable path and helper-file completeness, and restart the listener if it points to a stale/incomplete cache directory.
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
This is a good example of "remote control connected" not being strong enough as a health signal.
For diagnostics I would make the remote-control listener identity first-class, ideally in
codex doctorand in any mobile/desktop route health panel:codex.exe,codex-windows-sandbox-setup.exe,codex-command-runner.exeThen mobile can distinguish:
The important product invariant is that a control surface should report the route that will actually execute the next command, not just that some websocket is listening. That is the same invariant Faryo uses for its browser/mobile workbench over a tmux-backed live session:
https://github.com/Snailflyer/faryo
Thanks, this framing matches what we saw locally: "remote control connected" was true in the weak sense that some websocket listener existed, but it was not the route that could successfully execute the next command.
I reviewed the duplicate suggestions:
windows sandbox failed: spawn setup refreshfamily.The reason I think this issue is still useful as a separate Windows-specific report is the concrete failure mode: the listener on
127.0.0.1:14567was running from a cached directory that hadcodex.exebut did not have the Windows sandbox helper files next to it. The mobile route was therefore connected to a listener that could not spawncodex-windows-sandbox-setup.exe.A minimal product-side invariant might be:
For
codex doctor, the most useful single-line diagnostic would be something like:That would have made this immediately obvious without burning a long debugging session.
I maintain WinBridge Recovery for Windows Codex Desktop local runtime/state recovery: https://github.com/zemeng5208/winbridge-recovery
This is adjacent to the project's current scope in a useful way: the failure is not that the latest runtime bundle is missing, but that a live process is still bound to an older incomplete hashed Codex bin directory containing
codex.exewithout the helper set it later expects. That is the same class of version/provenance split WinBridge already checks for Browser/Computer Use runtime paths after Desktop updates.v3.1.1 validates the current installed package plus the official CLI/helper set (
codex.exe,codex-windows-sandbox-setup.exe,codex-command-runner.exe, etc.) and detects stale hash/version references before using them. A similar diagnostic for a remote-control listener should compare the listener executable path against the current complete runtime rather than treating “port is listening” as healthy.I want to keep the boundary clear: WinBridge currently focuses on Browser/Chrome/Computer Use recovery and does not yet manage the Remote Control listener lifecycle or restart port 14567 automatically. So I would treat this issue as a strong candidate for extending its diagnostics, not claim that v3.1.1 already repairs every remote-control case.
The useful invariant is the same: never switch or keep a runtime active unless the exact referenced version/hash directory is complete and validated.