Codex Desktop Remote SSH to Windows OpenSSH fails when default shell is PowerShell

Open 💬 9 comments Opened May 15, 2026 by omid-web

What version of the Codex App are you using?

Codex Desktop 26.513.20950 on macOS.

Remote Codex CLI observed:

  • Windows native Codex CLI: codex-cli 0.130.0-alpha.5
  • WSL/Linux Codex CLI workaround: codex-cli 0.130.0

What subscription do you have?

ChatGPT Pro

What platform is your computer?

Local client:

  • macOS on arm64
  • Codex Desktop app

Remote host:

  • Windows laptop over OpenSSH
  • Windows OpenSSH default shell set to PowerShell 7 (pwsh.exe)
  • Passwordless SSH key auth succeeds
  • Remote Windows workspace path: C:\MethodDev
  • codex app-server --help works when run manually in PowerShell

What issue are you seeing?

Codex Desktop Remote SSH discovers the Windows SSH host and authenticates successfully, but the connection fails during app-server bootstrap because the Desktop SSH transport sends POSIX login-shell bootstrap code to a PowerShell remote shell.

The failing remote command in app breadcrumbs includes a POSIX shell probe/exec shape like:

exec "$SHELL" -i -c '... if ( -r /etc/csh.login ) source ... exec /bin/sh -c "$CODEX_REMOTE_PAYLOAD" ...'

Because the remote OpenSSH login shell is PowerShell 7, PowerShell parses that POSIX/csh/sh syntax and fails with:

ParserError:
Line |
   1 | . ec "$SHELL" -i -c '\''set loginsh=1; if ( -r /etc/csh.login ) source ...
     |                                                               ~
     | Missing statement block after if ( condition ).

The Codex Desktop UI then reports the SSH connection as failed/reconnecting.

This appears related to shell compatibility issues such as #18183 and #19302, but this case is specifically native Windows OpenSSH with PowerShell as the configured default shell. In this setup, normal SSH and manual codex app-server invocation both work; the failure is the Desktop Remote SSH bootstrap assuming a POSIX-compatible login shell.

What steps can reproduce the bug?

  1. On a Windows machine, install OpenSSH Server and Codex CLI/Desktop.
  2. Configure Windows OpenSSH to use PowerShell 7 as the default shell, for example:
New-ItemProperty `
  -Path "HKLM:\SOFTWARE\OpenSSH" `
  -Name DefaultShell `
  -Value "C:\Program Files\PowerShell\7\pwsh.exe" `
  -PropertyType String `
  -Force
Restart-Service sshd
  1. From a Mac, verify SSH works and lands in PowerShell 7:
ssh windows-host '$PSVersionTable.PSVersion.ToString(); (Get-Location).Path; codex app-server --help'
  1. In Codex Desktop on macOS, add/select the SSH host under Settings -> Connections -> SSH.
  2. Enable the connection.
  3. Observe that the connection fails/retries.
  4. Inspect Codex Desktop breadcrumbs/logs; they show a PowerShell ParserError from the POSIX login-shell bootstrap.

What is the expected behavior?

Codex Desktop Remote SSH should support Windows OpenSSH hosts whose default shell is PowerShell, or at least fail with a clear diagnostic that the current Desktop Remote SSH bootstrap requires a POSIX-compatible shell.

A product-level fix could be one of:

  1. Detect PowerShell/Windows remote shells and use a PowerShell-native bootstrap path.
  2. Allow per-connection configuration of a bootstrap shell/command, so users can keep PowerShell as their interactive SSH shell while Codex uses an alternate shell for app-server startup.
  3. Detect unsupported shells before running POSIX syntax and show a clear actionable error.

Workaround

A WSL-backed SSH target works because it gives Codex a POSIX shell:

  • run an SSH server inside WSL on another port, e.g. 2222
  • connect Codex Desktop to that WSL SSH alias instead of the Windows OpenSSH alias
  • install Linux Codex CLI in WSL so codex app-server is on PATH
  • use /mnt/c/<workspace> for Windows project files
  • invoke Windows/IIS/PowerShell tools explicitly from WSL with pwsh.exe, powershell.exe, or cmd.exe

That workaround is usable, but it means native Windows OpenSSH + PowerShell is not a first-class Codex Desktop Remote SSH target today.

View original on GitHub ↗

9 Comments

omid-method · 3 months ago

Adding a concrete repro from my Windows laptop / WSL-backed Codex Desktop setup, based on a live debugging session.

Environment/context:

  • Codex Desktop is connected to the Windows laptop through the WSL workspace path /mnt/c/MethodDev.
  • The shell Codex gets is WSL Ubuntu (bash) on the Windows laptop, not native Windows PowerShell.
  • Files under C:\MethodDev are readable/writable through /mnt/c/MethodDev.
  • Windows tooling exists and is installed on the host:
  • PowerShell 7: C:\Program Files\PowerShell\7\pwsh.exe
  • Windows PowerShell: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  • .NET: C:\Program Files\dotnet\dotnet.exe
  • Method CLI: C:\Users\Omid Rajabi\.dotnet\tools\mtd.exe

What fails:

From the Codex WSL shell, launching Windows executables through WSL interop fails before the target process can produce normal output.

Minimal repro:

'/mnt/c/Program Files/PowerShell/7/pwsh.exe' -NoProfile -Command '$PSVersionTable.PSVersion.ToString()'

Observed output:

<3>WSL (2 - ) ERROR: UtilBindVsockAnyPort:307: socket failed 1

When retried through Codex's escalated command path, the process appeared to start but then exited with:

<3>WSL (...) ERROR: UtilAcceptVsock:271: accept4 failed 110

This is not specific to pwsh.exe. Similar attempts to launch Windows executables from the WSL-backed Codex session hit the same class of failure:

'/mnt/c/Program Files/dotnet/dotnet.exe' ...
'/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe' ...
'/mnt/c/Windows/System32/cmd.exe' /c ...
'/mnt/c/Users/Omid Rajabi/.dotnet/tools/mtd.exe' ...

Concrete workflow impact:

I asked Codex to run the local Method workspace health check. The normal command is:

cd C:\MethodDev
mtd healthcheck run -a

Inside the Codex WSL shell:

  • mtd was not on the Linux PATH.
  • Linux dotnet was not installed.
  • The Windows mtd.exe global tool was found at C:\Users\Omid Rajabi\.dotnet\tools\mtd.exe.
  • But invoking Windows mtd.exe, pwsh.exe, powershell.exe, cmd.exe, or dotnet.exe from Codex failed because WSL interop itself failed.

Expected behavior:

A WSL-backed Codex Desktop session on Windows should be able to invoke host Windows executables through normal WSL interop, especially for workflows where the repo lives under /mnt/c and local development depends on Windows-only tools such as IIS, PowerShell, Windows .NET, and locally installed CLIs.

Actual behavior:

Codex can read and edit the workspace under /mnt/c, but cannot cross the WSL-to-Windows process boundary. That blocks local Windows/IIS/PowerShell workflows from inside Codex even though the underlying tools are installed and should be callable from an ordinary WSL terminal.

One additional note: trying to use the codex-work SSH alias from this WSL environment also failed with DNS/alias resolution:

ssh: Could not resolve hostname codex-work: Temporary failure in name resolution

So, in this setup, there was no working fallback from the Codex WSL session to native Windows execution.

bookHsu-shinher · 3 months ago

Adding another anonymized repro from a Windows Codex Desktop host.

Environment:

  • Local Codex Desktop on Windows: 26.513.4821.0
  • Local OpenSSH client/server: OpenSSH_for_Windows_9.5p2, LibreSSL 3.8.2
  • Remote target is the same Windows machine via local loopback OpenSSH (127.0.0.1:<non-default-port>)
  • Windows account is a domain account and local administrator; user/domain/hostname are redacted
  • Codex CLI on PATH inside SSH login shell: codex-cli 0.130.0
  • SSH public-key auth succeeds
  • sshd was restricted to loopback only for the repro

What works outside Codex Desktop:

ssh <redacted-host-alias>
ssh <redacted-host-alias> 'codex --version'

The second command returns:

codex-cli 0.130.0

What fails in Codex Desktop:

Settings -> Connections -> SSH connections from this PC -> add/enable the Windows OpenSSH alias.

After fixing key auth, the UI shows that SSH authentication succeeds:

Authenticated to 127.0.0.1 ([127.0.0.1]:<redacted-port>) using "publickey".

Then the connection still fails because the bootstrap appears to send POSIX/csh/sh login-shell probing code to a Windows shell. The UI error includes escaped/ANSI-contaminated output with fragments like:

exec "$SHELL" -i -c 'set loginsh=1; if ( -r /etc/csh.login ) source ...'
Missing statement block after if ( condition ).

I tried both native Windows OpenSSH defaults and setting the OpenSSH default shell to PowerShell 7. The result is the same class of failure: SSH auth succeeds, but the remote bootstrap assumes POSIX shell semantics and PowerShell cannot parse the command.

Additional notes:

  • This is not a key, firewall, or PATH issue: public-key auth works, the host is reachable, and codex --version works over the same SSH alias.
  • The confusing part for users is that the Codex Desktop UI only surfaces this as a generic SSH connection failure even though the failure is after successful authentication.
  • A clearer diagnostic would help, e.g. "Windows OpenSSH/PowerShell remote shells are not currently supported for Remote SSH; use WSL/Linux or configure a POSIX-compatible shell."

This matches the original issue report: native Windows OpenSSH with PowerShell/cmd as the remote shell is not currently handled by the Codex Desktop Remote SSH bootstrap.

mmiladinov · 1 month ago

I am also seeing the same issue.

dustovo · 1 month ago

How to fix this issue?

Codex Desktop version: 26.707.12708.0
Remote OS: Windows
Remote SSH server: Windows OpenSSH
Remote default shell: PowerShell 7.6.3
Failure stage: remote_codex_lookup
Error type: AppServerSshSetupError

SSH authentication succeeds and this works:

ssh remote-server 'codex --version'
codex-cli 0.144.5

However, Codex Desktop sends a POSIX bootstrap payload beginning with:

sh -c 'if [ -z "$SHELL" ] ...

PowerShell then fails with:

ParserError: Missing statement block after if ( condition ).

The remote PATH, SSH key, Codex CLI, Node.js, and PowerShell configuration have all been verified working.

eddy961206 · 26 days ago

same issue here

TomaxMe · 8 days ago

same issue here

padeoe · 8 days ago

same issue

ShiTan-677 · 6 days ago

Adding an independent, anonymized reproduction from a macOS client to a native Windows OpenSSH host. This matches the same root cause with the Windows default cmd.exe shell (rather than PowerShell).

Environment

  • Client: ChatGPT/Codex Desktop for macOS 26.803.61601 (build 6396)
  • Client OpenSSH: OpenSSH_10.2p1
  • Remote: Windows 11 Pro 10.0.26200.9168
  • Remote SSH server banner: OpenSSH_for_Windows_9.5
  • Remote Codex CLI: codex-cli 0.147.0
  • Remote account: standard (non-admin) Windows user
  • Authentication: public key
  • Remote OpenSSH default shell: native cmd.exe
  • The host is a concrete alias in ~/.ssh/config and was auto-discovered by Desktop; it was not manually entered in the app.

Checks that succeed outside Desktop

Using the same SSH alias and identity:

ssh <alias>
where codex
C:\Users\<redacted>\Tools\Codex\bin\codex.exe

codex --version
codex-cli 0.147.0

codex login status
Logged in using ChatGPT

The non-interactive app-server probe also succeeds:

ssh <alias> "codex app-server --help"

It prints the normal codex app-server help and exits successfully. The CLI lives in a normal NTFS directory (not the standalone installer's junction), so this is not a PATH or reparse-point failure.

Desktop failure

Desktop discovers the alias:

hostId=remote-ssh-discovered:<alias>
discoveredConnectionCount=1

SSH authentication succeeds, and the client can see the Windows SSH implementation:

Remote protocol version 2.0, remote software version OpenSSH_for_Windows_9.5
Authenticated to <redacted-host> using "publickey".

Immediately afterward, during the Codex path probe, Desktop sends a POSIX bootstrap to the native Windows shell:

Sending command: sh -c 'if [ -z "$SHELL" ] || [ ! -x "$SHELL" ]; then ...
case "${SHELL##*/}" in ...
exec /bin/sh -c "$CODEX_REMOTE_PAYLOAD" ...
if command -v codex >/dev/null 2>&1; then exit 0; fi'

The Windows shell rejects it (the original localized output is mojibake in the app log; translated):

'sh' is not recognized as an internal or external command
'[' is not recognized as an internal or external command
Exit status 255

The final failure is:

errorName=AppServerSshSetupError
sshSetupStage=remote_codex_lookup
operation=codex_path_probe

So Desktop never reaches the already-working codex.exe or starts the app server.

Expected behavior

For a native Windows OpenSSH host, Desktop should select a Windows-native bootstrap (PowerShell or cmd-aware), locate codex.exe using the remote login shell's Windows PATH, and start the remote app server without requiring a machine-wide Git Bash default-shell override.

The current official SSH workflow says that Desktop starts the remote Codex app server through SSH using the remote user's login shell and requires codex on that shell's PATH: https://learn.chatgpt.com/docs/remote-connections#connect-to-an-ssh-host

This reproduction satisfies those prerequisites; the blocker is specifically the unconditional POSIX bootstrap at remote_codex_lookup.

Pyromaniac6669 · 4 days ago

I am experiencing the same issue. SSH authentication and terminal access work, but the Codex Desktop SSH connection fails during bootstrap with a PowerShell parser error. I hope this can be fixed soon. Thank you!