Skip to content

Remote SSH connection fails when Node.js is installed via nvm: "No codex found in PATH" and silent app-server launch failure #19744

Open

Description

@danohn

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

Version 26.422.30944 (2080)

What subscription do you have?

ChatGPT Plus

What platform is your computer?

Darwin 25.4.0 arm64 arm

What issue are you seeing?

Codex Desktop fails to connect to remote SSH hosts when Node.js (and the codex CLI) is installed via nvm. There are two distinct failures:

  1. "No codex found in PATH" — the PATH probe uses a login+interactive shell (/bin/bash -l -i) but nvm may not initialise, so codex isn't found even though it's installed.

  2. Silent ECONNRESET after the probe succeeds — even when the PATH probe passes (e.g. after symlinking codex to /usr/local/bin), the app-server launch fails silently. Codex Desktop launches the server via a non-interactive SSH command using /usr/bin/env node, which can't find node since nvm isn't loaded. The WebSocket immediately closes with code 1006 (ECONNRESET) and no actionable error is shown in the UI. The actual error (/usr/bin/env: 'node': No such file or directory) is only visible in /tmp/codex-app-server-ssh-ws-v0.log on the remote.

What steps can reproduce the bug?

  1. Install Node.js via nvm on a remote Linux machine
  2. Install the codex CLI via npm (npm install -g @openai/codex)
  3. Add the remote host to ~/.ssh/config on the local macOS machine
  4. Open Codex Desktop and attempt to enable the remote SSH connection
  5. Observe "No codex found in PATH" error
  6. Symlink codex to /usr/local/bin/codex on the remote to get past step 5
  7. Observe persistent connection failure with ECONNRESET — no actionable error shown in the UI

What is the expected behavior?

Codex Desktop should use the same shell environment for both the PATH probe and the app-server launch, so nvm-managed binaries work consistently without manual symlinks. If the launch does fail, the actual error from the remote (e.g. node not found) should be surfaced in the UI rather than a generic connection failure.

Additional information

  • Codex Desktop version: 0.125.0-alpha.3 (macOS)
  • Remote OS: Linux (Debian/Ubuntu), Node.js installed via nvm v24.15.0
  • The workaround requires two symlinks on the remote machine:
ln -sf ~/.nvm/versions/node/$(node --version)/bin/codex /usr/local/bin/codex
ln -sf ~/.nvm/versions/node/$(node --version)/bin/node /usr/local/bin/node
  • The real server-side error is logged to /tmp/codex-app-server-ssh-ws-v0.log on the remote, which is not currently surfaced anywhere in Codex Desktop

Activity

  1. added
    appIssues related to the Codex desktop app
    on Apr 27, 2026
  2. added
    bugSomething isn't working
    app-serverIssues involving app server protocol or interfaces
    connectivityIssues involving networking or endpoint connectivity problems (disconnections)
    on Apr 27, 2026
  3. github-actions commented on Apr 27, 2026

    @github-actions
    Contributor

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

    Powered by Codex Action

  4. danohn commented on Apr 27, 2026

    @danohn
    Author

    The root cause is that /bin/sh on Debian/Ubuntu is dash, not bash. Codex Desktop's
    PATH probe runs /bin/sh -lc '...', which sources /etc/profile and ~/.profile but
    NOT ~/.bashrc where nvm is initialised. As a result, nvm's bin directory is absent
    from the PATH seen by Codex Desktop, even though it is present in regular interactive
    SSH sessions.

    Dash PATH (what Codex Desktop sees):
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

    Bash PATH (what a normal SSH session sees):
    /root/.local/bin:/root/.nvm/versions/node/v24.15.0/bin:/usr/local/sbin:/usr/local/bin:...

  5. lmxx1234567 commented on Apr 27, 2026

    @lmxx1234567

    @danohn Thanks for pointing that out. Here’s my workaround: add the NVM initialization to ~/.profile from ~/.bashrc.

    export NVM_DIR="$HOME/.nvm"
    if [ -s "$NVM_DIR/nvm.sh" ]; then
      . "$NVM_DIR/nvm.sh"
    fi
  6. willdla commented on May 15, 2026

    @willdla

    @danohn Thanks for pointing that out. Here’s my workaround: add the NVM initialization to ~/.profile from ~/.bashrc.

    export NVM_DIR="$HOME/.nvm"
    if [ -s "$NVM_DIR/nvm.sh" ]; then
    . "$NVM_DIR/nvm.sh"
    fi

    this works

  7. jiachangliu commented on Jun 5, 2026

    @jiachangliu

    Adding one more data point: I hit the same underlying issue from the ChatGPT iPhone Codex UI connecting to a remote Linux host.

    In my interactive shell, Codex worked because nvm was loaded:

    command -v codex
    codex --version
    codex app-server --help >/dev/null && echo app-server-ok

    But a clean login-shell simulation could not find codex:

    env -i HOME="$HOME" USER="$USER" LOGNAME="$LOGNAME" SHELL=/bin/bash /bin/bash -lc \
    'echo "PATH=$PATH"; command -v codex; codex --version; codex app-server --help >/dev/null && echo app-server-ok'

    Instead of moving all nvm initialization into ~/.profile, this user-local wrapper also fixed it for me:

    NVM_NODE_BIN="$(dirname "$(command -v node)")"
    REAL_CODEX="$(command -v codex)"
    
    mkdir -p "$HOME/.local/bin"
    
    cat > "$HOME/.local/bin/codex" <<EOF
    #!/usr/bin/env bash
    export PATH="$NVM_NODE_BIN:\$PATH"
    exec "$REAL_CODEX" "\$@"
    EOF
    
    chmod +x "$HOME/.local/bin/codex"

    Then the clean-shell check found:

    $HOME/.local/bin/codex
    codex-cli ...
    app-server-ok
    

    After that, ChatGPT iPhone Codex UI was able to connect to the remote Linux host.

    This works if ~/.local/bin is already on the login-shell PATH, which is common on Linux via ~/.profile. It avoids sudo, avoids changing /usr/local/bin, and avoids sourcing all of nvm from ~/.profile.

    The key difference from moving nvm initialization into ~/.profile is scope: this does not make every login shell load nvm; it only makes codex work when something tries to run codex.

  8. sigmalko commented on Oct 17, 2026

    @sigmalko

    Additional reproducible case: Docker, custom login shell, and PATH reset

    I encountered a closely related issue with Codex Desktop on Windows connecting to Codex CLI inside a Linux Docker container.

    Unlike the original report, this environment does not use nvm. Instead, Codex is installed through npm with a custom global prefix.

    Environment:

    • Client: Codex Desktop on Windows
    • Remote: Linux Docker container over SSH
    • Codex CLI: 0.163.0
    • Installation: /home/agent/.npm-global/bin/codex
    • User login shell: /usr/local/bin/agent-shell

    Normal SSH successfully locates Codex:

    ssh -T cracow 'command -v codex; codex --version'

    Output:

    /home/agent/.npm-global/bin/codex
    codex-cli 0.163.0
    

    However, Codex Desktop fails to detect the installed CLI.

    I captured the actual ssh.exe invocation launched by Codex Desktop using PowerShell's Get-CimInstance Win32_Process.

    The remote probe invokes:

    exec "$SHELL" -l -i -c '...'

    The custom login shell is:

    #!/usr/bin/env bash
    set -euo pipefail
    
    if [[ -r /run/agent-environment ]]; then
        source /run/agent-environment
    fi
    
    cd /workspaces
    exec /bin/bash "$@"

    The environment file contains the following PATH configuration:

    export PATH=/home/agent/.npm-global/bin:/usr/local/bin:/usr/bin:/bin

    Confirmed root cause

    The login/interactive Bash invocation resets PATH:

    /usr/local/bin/agent-shell -l -i -c 'echo "$PATH"'

    Output:

    /usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games
    

    The npm global bin directory has disappeared.

    Executing:

    /usr/local/bin/agent-shell -l -i -c 'codex --version'

    returns:

    bash: codex: command not found
    

    Exit code: 127.

    This reproduces a case where a normal SSH CLI lookup succeeds, but Codex Desktop's login-shell probe cannot find the same executable.

    Proposed workaround

    Add the npm global bin directory to the login-shell environment:

    echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bash_profile

    This workaround has been identified from the confirmed PATH reset, but I have not yet independently confirmed successful Codex Desktop reconnection after applying it.

    Suggested improvement

    It would be useful if Codex Desktop:

    1. Reported the effective PATH and executable lookup failure from its actual remote probe.
    2. Distinguished an unavailable CLI from a login-shell environment initialization problem.
    3. Used a consistent, documented environment for CLI discovery and app-server startup.
    4. Provided an explicit per-host executable directory override in the SSH connection settings.

    This issue is closely related to the nvm case, but demonstrates that the same underlying environment problem can occur with custom Docker entrypoints and login-shell wrappers, even without nvm.

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 workingconnectivityIssues involving networking or endpoint connectivity problems (disconnections)remote

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions