paperclipai/paperclip · critical · Error

Command not found in PATH: "ssh"

Error message

Command not found in PATH: "ssh"

What it means

Thrown by the spawn-target resolver when a remoteExecution spec is configured but the local `ssh` binary cannot be found in PATH (resolveCommandPath returned null). Remote runs require a local ssh client to connect to the sandbox host; without it the adapter cannot build an SSH spawn target and fails fast.

Source

Thrown at packages/adapter-utils/src/server-utils.ts:2354

  return path.join(fallbackRoot, "System32", "cmd.exe");
}

async function resolveSpawnTarget(
  command: string,
  args: string[],
  cwd: string,
  env: NodeJS.ProcessEnv,
  options: {
    remoteExecution?: RemoteExecutionSpec | null;
    remoteEnv?: Record<string, string> | null;
    localProcessSandbox?: LocalProcessSandboxOptions | null;
  } = {},
): Promise<SpawnTarget> {
  const remote = options.remoteExecution ?? null;
  if (remote) {
    const sshResolved = await resolveCommandPath("ssh", process.cwd(), env);
    if (!sshResolved) {
      throw new Error('Command not found in PATH: "ssh"');
    }
    const spawnTarget = await buildSshSpawnTarget({
      spec: remote,
      command,
      args,
      env: Object.fromEntries(
        Object.entries(options.remoteEnv ?? {}).filter((entry): entry is [string, string] => typeof entry[1] === "string"),
      ),
    });
    return {
      command: sshResolved,
      args: spawnTarget.args,
      cwd: process.cwd(),
      cleanup: spawnTarget.cleanup,
    };
  }

  const resolved = await resolveCommandPath(command, cwd, env);

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Install an ssh client (e.g. 'apt-get install -y openssh-client') in the runtime image.
  2. Ensure PATH passed to the adapter includes the directory containing ssh (often /usr/bin).
  3. If you did not intend remote execution, clear the remoteExecution option / config so it runs locally.
  4. On Windows, enable the OpenSSH optional feature or add its install dir to PATH.
Defensive patterns

Strategy: validation

Validate before calling

import { commandExists } from './path-helpers';
if (remoteExecution && !(await commandExists('ssh', env))) {
  throw new Error('ssh client required for remoteExecution but not found in PATH');
}

Try / catch

try { await resolveCommandPath('ssh', cwd, env); } catch { /* resolveCommandPath returns null, doesn't throw */ }

Prevention

When it happens

Trigger: Calling the spawn/execute path with options.remoteExecution set, on a machine whose PATH does not contain an ssh executable. resolveCommandPath('ssh', cwd, env) returns null and the error is raised before any SSH connection attempt.

Common situations: Minimal container/CI image without openssh-client installed; PATH env stripped when spawning the adapter process; Windows host without OpenSSH in PATH; a sandboxed runtime that intentionally omits ssh.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/f01295cc5a507898. Report an issue: GitHub.