{"record":{"id":"e495fe9717cd7e50","repo":"paperclipai/paperclip","slug":"command-command-is-not-installed-or-not-on-pa","errorCode":null,"errorMessage":"Command \"${command}\" is not installed or not on PATH in the sandbox environment${installDetail}.${probeStderr}","messagePattern":"Command \"(.+?)\" is not installed or not on PATH in the sandbox environment(.+?)\\.(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/execution-target.ts","lineNumber":563,"sourceCode":"      } else if ((installResult.exitCode ?? 0) !== 0) {\n        const tail = (text: string) =>\n          text.split(/\\r?\\n/).filter((line) => line.trim().length > 0).slice(-2).join(\" | \").slice(0, 240);\n        const reason = tail(installResult.stderr || installResult.stdout) || `exit ${installResult.exitCode ?? \"?\"}`;\n        installFailureDetail = `install command exited ${installResult.exitCode ?? \"?\"}: ${reason}`;\n      }\n    } catch (err) {\n      installFailureDetail = `install command threw: ${err instanceof Error ? err.message : String(err)}`;\n    }\n    probe = await probeSandboxCommandResolvable(command, target);\n    if (probe.resolved) return;\n    if (probe.timedOut) {\n      throw new Error(`Timed out checking command \"${command}\" on sandbox target.`);\n    }\n  }\n\n  const probeStderr = probe.stderr.length > 0 ? ` probe stderr: ${probe.stderr}` : \"\";\n  const installDetail = installFailureDetail ? `; ${installFailureDetail}` : \"\";\n  throw new Error(\n    `Command \"${command}\" is not installed or not on PATH in the sandbox environment${installDetail}.${probeStderr}`,\n  );\n}\n\nexport async function resolveAdapterExecutionTargetCommandForLogs(\n  command: string,\n  target: AdapterExecutionTarget | null | undefined,\n  cwd: string,\n  env: NodeJS.ProcessEnv,\n): Promise<string> {\n  if (target?.kind === \"remote\" && target.transport === \"sandbox\") {\n    return `sandbox://${target.providerKey ?? \"provider\"}/${target.leaseId ?? \"lease\"}/${target.remoteCwd} :: ${command}`;\n  }\n  return await resolveCommandForLogs(command, cwd, env, {\n    remoteExecution: adapterExecutionTargetToRemoteSpec(target),\n  });\n}\n","sourceCodeStart":545,"sourceCodeEnd":581,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/execution-target.ts#L545-L581","documentation":"Thrown by ensureSandboxCommandResolvable as the final fallthrough: the command is not resolvable on PATH and did not time out. This is the honest 'binary is genuinely missing' error. If an install command was attempted and failed, the installFailureDetail is appended so the developer can see why the install did not fix the problem.","triggerScenarios":"ensureSandboxCommandResolvable(command, target, installCommand, timeoutSec) where probeSandboxCommandResolvable returned { resolved: false, timedOut: false }. The install command either was not provided, ran but exited non-zero, or threw — all captured into installFailureDetail.","commonSituations":"The CLI binary was never baked into the sandbox image and no install command was configured; the install command points to a private registry that is unreachable from the sandbox; the install command installed to a PATH location not covered by the sandbox's login profile; the binary name in the adapter config does not match what the install command places on PATH.","solutions":["Bake the CLI binary into the sandbox image so it is on PATH at lease start, eliminating the need for an install command.","If using an install command, verify it installs the binary to a directory on the sandbox's PATH and that the login profile sources correctly.","Check the appended installFailureDetail for the specific exit code or error message and address that root cause.","Verify the command name passed to ensureSandboxCommandResolvable matches the binary name the install command produces."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Pre-probe before calling ensureSandboxCommandResolvable\nasync function isCommandOnSandboxPath(command: string, target: AdapterSandboxExecutionTarget): Promise<boolean> {\n  const probe = await probeSandboxCommandResolvable(command, target);\n  return probe.resolved;\n}","typeGuard":null,"tryCatchPattern":"try {\n  await ensureSandboxCommandResolvable(command, target, installCommand, timeoutSec);\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"not installed or not on PATH\")) {\n    // Surface a user-friendly message about the missing CLI\n    throw new Error(`Adapter CLI '${command}' is missing in the sandbox. Check the image or install command.`);\n  }\n  throw err;\n}","preventionTips":["Bake required CLI binaries into the sandbox image at build time.","Test the install command in the sandbox image interactively before relying on it in production.","Ensure the install command writes to a PATH location sourced by the sandbox login shell."],"tags":["sandbox","path","execution-target","install","adapter-utils"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}