{"record":{"id":"f425b51782887fff","repo":"paperclipai/paperclip","slug":"action-failed-with-exit-code-result-exitcode","errorCode":null,"errorMessage":"${action} failed with exit code ${result.exitCode ?? \"null\"}${detail}","messagePattern":"(.+?) failed with exit code (.+?)(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/adapter-utils/src/command-managed-runtime.ts","lineNumber":130,"sourceCode":"\nfunction formatFailedCommandOutput(result: RunProcessResult): string {\n  const tail = (text: string): string => {\n    const trimmed = text.trim();\n    if (trimmed.length <= FAILED_COMMAND_OUTPUT_TAIL_CHARS) return trimmed;\n    return `...[truncated]\\n${trimmed.slice(-FAILED_COMMAND_OUTPUT_TAIL_CHARS)}`;\n  };\n  const stderr = tail(result.stderr);\n  const stdout = tail(result.stdout);\n  const parts: string[] = [];\n  if (stderr.length > 0) parts.push(`stderr: ${stderr}`);\n  if (stdout.length > 0) parts.push(`stdout: ${stdout}`);\n  return parts.length > 0 ? `:\\n${parts.join(\"\\n\")}` : \"\";\n}\n\nfunction requireSuccessfulResult(result: RunProcessResult, action: string): void {\n  if (result.exitCode === 0 && !result.timedOut) return;\n  const detail = formatFailedCommandOutput(result);\n  throw new Error(`${action} failed with exit code ${result.exitCode ?? \"null\"}${detail}`);\n}\n\nfunction bufferToArrayBuffer(buffer: Buffer): ArrayBuffer {\n  // Copy out of the (possibly pooled) Node Buffer so the ArrayBuffer we hand to\n  // the client transport owns exactly these bytes.\n  return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength) as ArrayBuffer;\n}\n\n// Named builder (Security Condition C3): extract an uploaded tarball into its\n// target directory as a clean destroy-then-replace, then remove the tarball.\n// Every path is shell-quoted; the fallback NEVER concatenates untrusted asset\n// keys / file names into the shell.\nfunction buildSyncInExtractDirectoryCommand(input: { remoteTarPath: string; targetDir: string }): string {\n  return (\n    `rm -rf ${shellQuote(input.targetDir)} && ` +\n    `mkdir -p ${shellQuote(input.targetDir)} && ` +\n    `tar -xf ${shellQuote(input.remoteTarPath)} -C ${shellQuote(input.targetDir)} && ` +\n    `rm -f ${shellQuote(input.remoteTarPath)}`","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/packages/adapter-utils/src/command-managed-runtime.ts#L112-L148","documentation":"Thrown by requireSuccessfulResult when a sandbox command executed via the command-managed runtime returns a non-zero exit code or times out. This is the generic failure wrapper for all shell commands run through runShell (makeDir, writeFile, readFile, listFiles, remove, run) and post-upload commands. The error message includes the action (the shell script or command label), the exit code (or 'null' for timeout), and a truncated tail of stderr and stdout.","triggerScenarios":"Any sandbox shell command returning exitCode !== 0 or timing out. This includes: mkdir failing due to permissions, base64 decode failing on corrupt data, tar extraction failing, 'wc -c' failing on a missing file, post-upload commands failing, install commands failing (though install failures are caught and warned, not thrown), and any command exceeding the timeout.","commonSituations":"The sandbox environment lacks expected tools (e.g., no base64, no dd, no tar). Permission denied on remote paths. Disk full on the sandbox. Network timeouts on provider-backed sandbox RPCs. A post-upload command (e.g., npm install) failing due to missing dependencies. The remote working directory was deleted during a run.","solutions":["Read the stderr/stdout tail in the error message to identify the specific shell error.","If the command timed out, increase the timeoutMs in the CommandManagedRuntimeSpec or per-command timeout.","Verify the sandbox has the required tools: check that bash/sh, base64, dd, tar, wc are available.","For post-upload command failures, run the failing command manually in the sandbox to reproduce and debug.","Check sandbox disk space and permissions if the error is I/O related."],"exampleFix":"// before: post-upload command fails (e.g., npm install in wrong cwd)\nconst ops: SandboxSyncOperation[] = [{\n  files: [{ kind: \"directory\", sourcePath: \"./proj\", targetPath: \"/workspace/proj\" }],\n  postUploadCommands: [{ command: \"npm install\", cwd: \"/workspace/wrong-path\" }],\n}];\n\n// after: correct cwd matching targetPath\nconst ops: SandboxSyncOperation[] = [{\n  files: [{ kind: \"directory\", sourcePath: \"./proj\", targetPath: \"/workspace/proj\" }],\n  postUploadCommands: [{ command: \"npm install\", cwd: \"/workspace/proj\" }],\n}];","handlingStrategy":"try-catch","validationCode":"// Pre-validate sandbox environment before running commands:\nasync function verifySandboxReady(client: SandboxManagedRuntimeClient): Promise<void> {\n  // Check essential tools exist\n  const tools = ['bash', 'base64', 'dd', 'tar', 'wc'];\n  for (const tool of tools) {\n    try {\n      await client.run(`command -v ${tool}`, { timeoutMs: 5000 });\n    } catch {\n      throw new Error(`Required tool '${tool}' is missing from the sandbox environment.`);\n    }\n  }\n}\n\n// Call before syncIn or other operations:\nawait verifySandboxReady(client);","typeGuard":null,"tryCatchPattern":"try {\n  await client.run(command, { timeoutMs });\n} catch (error) {\n  if (error instanceof Error && /failed with exit code/.test(error.message)) {\n    // Parse the exit code and stderr/stdout tail from the message\n    const match = error.message.match(/exit code (\\d+)/);\n    const exitCode = match ? Number(match[1]) : null;\n    console.error(`Command failed (exit ${exitCode}):`, error.message);\n    // Retry with adjusted timeout, or report to the caller\n  }\n  throw error;\n}","preventionTips":["Ensure the sandbox has standard POSIX tools: bash/sh, base64, dd, tar, wc, mkdir, rm, mv, chmod.","Set adequate timeoutMs values—large file operations may need more time on provider-backed sandboxes.","Validate post-upload commands locally before configuring them in syncIn operations.","Check sandbox disk space before large file uploads or tar extractions.","Handle non-zero exits gracefully—some commands (e.g., command -v) use non-zero exit as a signal, not an error."],"tags":["runtime","command-execution","sandbox","adapter-utils"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}