{"record":{"id":"fb17c0a3496bb93e","repo":"paperclipai/paperclip","slug":"could-not-resolve-remote-path-for-managed-github-l","errorCode":null,"errorMessage":"Could not resolve remote PATH for managed GitHub launchers","messagePattern":"Could not resolve remote PATH for managed GitHub launchers","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/execution-target.ts","lineNumber":1569,"sourceCode":"  env: Record<string, string>,\n): Promise<string> {\n  if (!target) return env.PATH || process.env.PATH || \"/usr/bin:/bin\";\n  const configuredPath = sanitizeRemoteExecutionEnv(env).PATH;\n  if (configuredPath !== undefined) return configuredPath;\n\n  // The provider owns login/profile setup. Query its effective PATH before\n  // staging BASH_ENV, rather than substituting the controller's toolchain or\n  // a minimal PATH that hides legacy NVM/user-local agent installations.\n  const result = await adapterExecutionTargetCommandRunner(target).execute({\n    command: \"sh\",\n    args: [\"-c\", \"printf '\\\\000%s\\\\000' \\\"$PATH\\\"\"],\n    cwd: target.remoteCwd,\n    timeoutMs: 15_000,\n  });\n  // Frame the value so login banners cannot become executable search paths.\n  const remotePath = result.stdout.match(/\\0([^\\0]+)\\0/)?.[1];\n  if (result.timedOut || result.exitCode !== 0 || !remotePath) {\n    throw new Error(\"Could not resolve remote PATH for managed GitHub launchers\");\n  }\n  return remotePath;\n}\n\n/** Read only execution-target Git context; never import the controller's credentials into SSH. */\nexport async function prepareGitHubExecutionEnvironment(input: {\n  target: AdapterExecutionTarget | null | undefined;\n  cwd: string;\n  env: Record<string, string>;\n  hostCredentials: boolean;\n  networkAccess: boolean;\n}): Promise<Record<string, string>> {\n  const script = String.raw`\nconst fs = require('node:fs');\nconst path = require('node:path');\nconst cp = require('node:child_process');\nconst env = {};\nenv.PAPERCLIP_RUNNER_NETWORK_ROOTS = JSON.stringify(['/etc/resolv.conf','/etc/hosts','/etc/nsswitch.conf','/etc/ssl/certs','/etc/ssl/cert.pem'].flatMap(p => { try { return [fs.realpathSync(p)]; } catch { return []; } }));","sourceCodeStart":1551,"sourceCodeEnd":1587,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/adapter-utils/src/execution-target.ts#L1551-L1587","documentation":"To run managed GitHub launchers remotely, the code probes the remote host for its PATH by running a shell command whose stdout embeds the PATH between NUL delimiters (framing so login banners cannot be mistaken for the value). This error means the probe timed out, exited non-zero, or no NUL-framed value could be extracted — so a trustworthy remote PATH is unavailable.","triggerScenarios":"Remote SSH command timing out (15s), remote shell failing (exit != 0), login banners or shell init output interfering so the /\\0([^\\0]+)\\0/ match fails, or the remote shell printing nothing framed.","commonSituations":"Remote host with slow shell startup files (nvm, conda) exceeding the timeout; restricted SSH environments where PATH is not exported; middleware printing banners without the expected NUL framing; transient network failures.","solutions":["SSH to the target manually and confirm `sh -lc 'echo $PATH'` works and is fast","Trim slow shell init files (nvm/conda lazy-load) so the probe finishes within 15s","Verify the remote default shell emits the PATH cleanly and retry","Check network/SSH stability to the remote target"],"exampleFix":"// before: probe times out due to slow .bashrc\n// after: make init lazy\n# ~/.bashrc\n[[ -r ~/.nvm/nvm.sh ]] && lazy_load_nvm","handlingStrategy":"retry","validationCode":"const probe = await runner.execute({ command: 'sh', args: ['-c', 'echo $PATH'], timeoutMs: 10000 });\nif (probe.timedOut || probe.exitCode !== 0) throw new Error('remote PATH probe unhealthy before launch');","typeGuard":null,"tryCatchPattern":"try {\n  const p = await resolveRemotePath(target);\n} catch (e) {\n  if (String(e.message).includes('Could not resolve remote PATH')) {\n    // retry once after warming the SSH connection\n  } else throw e;\n}","preventionTips":["Keep remote shell init files fast (lazy-load nvm/conda)","Ensure the remote login shell exports PATH cleanly without banner noise to stdout","Warm SSH connections before time-sensitive probes","Increase tolerance by checking target health before launcher setup"],"tags":["remote-execution","ssh","environment"],"backgroundTag":"command-not-found","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}