{"record":{"id":"37f5a8a478ca842a","repo":"can1357/oh-my-pi","slug":"the-configured-command-binary-does-not-exist","errorCode":null,"errorMessage":"the configured command binary does not exist","messagePattern":"the configured command binary does not exist","errorType":"exception","errorClass":"DestinationUnavailableError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts","lineNumber":261,"sourceCode":"\t\t\tif (protocol === \"ftps\" && port !== 990) args.push(\"--ssl-reqd\");\n\t\t\targs.push(ftpUploadUrl(protocol, host, port, destinationPath));\n\t\t\ttry {\n\t\t\t\tconst process = Bun.spawn(args, {\n\t\t\t\t\tstdin: request.bytes,\n\t\t\t\t\tstdout: \"ignore\",\n\t\t\t\t\tstderr: \"pipe\",\n\t\t\t\t\tcwd: getSafeProjectCwd(),\n\t\t\t\t});\n\t\t\t\tconst stderr = await new Response(process.stderr as ReadableStream<Uint8Array>).text();\n\t\t\t\tconst exitCode = await process.exited;\n\t\t\t\tif (exitCode !== 0) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`${protocol.toUpperCase()} upload command exited with code ${exitCode}: ${stderr.trim().slice(-300)}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tif (errorCode(error) === \"ENOENT\") {\n\t\t\t\t\tthrow new DestinationUnavailableError(\"ftp\", \"the configured command binary does not exist\");\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn publication(\"ftp\", request, publicUrl(publicBase, directory, filename));\n\t\t},\n\t};\n}\n\nfunction createSharedFolderUploader(config: DestinationRuntimeConfig): BlobUploader {\n\tconst root = path.resolve(requiredStringOption(config, \"root\"));\n\tconst directory = optionString(config, \"path\");\n\tconst publicBase = requiredStringOption(config, \"publicBaseUrl\");\n\thttpBase(publicBase, \"publicBaseUrl\");\n\treturn {\n\t\tdestination: \"shared-folder\",\n\t\tasync upload(request) {\n\t\t\tconst filename = safeFileName(request);\n\t\t\tconst target = path.resolve(root, ...pathParts(directory), filename);","sourceCodeStart":243,"sourceCodeEnd":279,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/blob-broker/uploaders-self-hosted.ts#L243-L279","documentation":"A DestinationUnavailableError thrown during ftp/ftps upload when spawning the configured commandBinary fails with ENOENT — i.e. the path/name in options.commandBinary does not exist or is not executable on this machine. It is raised inside upload() because Bun.spawn rejects at call time, wrapped from the generic Error into a destination-unavailable signal.","triggerScenarios":"options.commandBinary points to a nonexistent file (e.g. /usr/local/bin/curl on a system that has /usr/bin/curl), a bare name not on the PATH of the agent process, or the binary exists but lacks the execute bit.","commonSituations":"Config authored on macOS (/usr/local/bin/curl via Homebrew) running in a Linux container; CI images without curl; PATH differences between the developer shell and the daemon running the broker; Docker minimal images.","solutions":["Locate the real curl path (which curl / command -v curl) and put that absolute path in options.commandBinary.","Install curl in the runtime environment where uploads execute.","If the binary exists, fix permissions (chmod +x) and confirm the broker process's PATH includes its directory.","Verify with a manual spawn from the same environment: /path/to/curl --version should succeed."],"exampleFix":"// before\n{ \"options\": { \"protocol\": \"ftp\", \"commandBinary\": \"/usr/local/bin/curl\", ... } }  // ENOENT in container\n// after\n{ \"options\": { \"protocol\": \"ftp\", \"commandBinary\": \"/usr/bin/curl\", ... } }","handlingStrategy":"validation","validationCode":"import { $which } from '@oh-my-pi/pi-utils';\nconst bin = dest.options?.commandBinary;\nif (bin && !(await $which(bin))) throw new Error(`commandBinary not found or not executable: ${bin}`);","typeGuard":null,"tryCatchPattern":"try {\n  await uploader.upload(request);\n} catch (err) {\n  if (err?.name === 'DestinationUnavailableError' && /command binary does not exist/.test(err.message)) {\n    // fail fast with operator guidance: fix commandBinary path or install curl\n  } else throw err;\n}","preventionTips":["Resolve commandBinary to an absolute path at config load (which curl) and store that.","Smoke-test the binary (curl --version) in the same environment/process PATH as the broker.","Bake curl into deployment images used for blob uploads.","Remember fallback PATH differs between interactive shells and daemons/containers — always use absolute paths there."],"tags":["ftp","curl","enoent","missing-binary"],"backgroundTag":"command-not-found","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}