{"record":{"id":"271943d5485ff39c","repo":"can1357/oh-my-pi","slug":"docker-not-found-on-path-required-for-cleanup","errorCode":null,"errorMessage":"docker not found on PATH (required for cleanup).","messagePattern":"docker not found on PATH \\(required for cleanup\\)\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/metaharness/src/runner.ts","lineNumber":1714,"sourceCode":"\t\t`${bold(`${st.cfg.dataset} complete`)} — ${green(`${totals.pass}/${totals.done} passed (${successPct.toFixed(1)}%)`)}\\n`,\n\t);\n\tprocess.stdout.write(\n\t\t`fail ${totals.fail} · error ${totals.error} · spend ${fmtUsd(totals.costUsd)} · elapsed ${fmtDur(elapsedMs)}\\n`,\n\t);\n\tprocess.stdout.write(\n\t\t`tokens: in ${fmtNum(totals.tokIn)} · out ${fmtNum(totals.tokOut)} · cache ${fmtNum(totals.tokCache)}\\n`,\n\t);\n\tprocess.stdout.write(`${dim(\"report:\")} ${reportPath}\\n`);\n\tprocess.stdout.write(`${dim(\"logs:  \")} ${logPath}\\n`);\n\tprocess.stdout.write(`${dim(\"trials:\")} ${jobDir}\\n`);\n\tif (exitCode !== 0) process.stdout.write(yellow(`harbor exited ${exitCode}; see harbor.log\\n`));\n\treturn { exitCode, jobName, jobDir, benchDir, tarball, elapsedMs, totals, reportPath };\n}\n\nasync function main(): Promise<void> {\n\tconst argv = process.argv.slice(2);\n\tif (argv[0] === \"cleanup\") {\n\t\tif (!which(\"docker\")) throw new Error(\"docker not found on PATH (required for cleanup).\");\n\t\trunDockerCleanup(true);\n\t\treturn;\n\t}\n\tlet cfg = parseArgs(argv);\n\tif (cfg.resume) cfg = resolveResumeConfig(cfg);\n\tconst exitCode = (await runBenchmark(cfg)).exitCode;\n\tprocess.exit(exitCode);\n}\n\nif (import.meta.main) {\n\tmain().catch((err: unknown) => {\n\t\tif (isTTY) process.stdout.write(`${ESC}?25h${ESC}?1049l`);\n\t\tprocess.stderr.write(red(`\\nerror: ${err instanceof Error ? err.message : String(err)}\\n`));\n\t\tprocess.exit(1);\n\t});\n}\n","sourceCodeStart":1696,"sourceCodeEnd":1731,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/metaharness/src/runner.ts#L1696-L1731","documentation":"The runner's explicit 'cleanup' subcommand requires the docker CLI to inspect and remove benchmark containers/volumes. It checks for docker before doing anything and throws immediately if the binary is missing, since cleanup cannot safely proceed without it.","triggerScenarios":"Calling the runner with 'cleanup' as the first CLI argument on a machine where which('docker') finds nothing.","commonSituations":"Running cleanup on a host without Docker Desktop/Engine installed; docker installed but not linked into PATH (e.g. manual install, PATH stripped in cron/CI); running the cleanup on a macOS host that only uses Apple container, not docker.","solutions":["Install Docker (Docker Desktop on macOS, Docker Engine on Linux) so `docker` is on PATH","Verify with: which docker && docker info","Fix PATH in the environment where cleanup runs (CI/cron often has a minimal PATH)","If no docker resources exist to clean, skip the cleanup subcommand"],"exampleFix":"// before\n$ runner cleanup\n// Error: docker not found on PATH (required for cleanup).\n\n// after (macOS)\n$ brew install --cask docker && open -a Docker  # start daemon\n$ runner cleanup","handlingStrategy":"validation","validationCode":"import { which } from \"@oh-my-pi/pi-utils\";\nif (process.argv[2] === \"cleanup\" && !which(\"docker\")) {\n  console.error(\"cleanup requires docker on PATH; install Docker first\");\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await runCleanup();\n} catch (err) {\n  if (err instanceof Error && err.message.includes(\"docker not found on PATH\")) {\n    console.error(\"Install Docker (Desktop/Engine) and ensure `docker` is on PATH before cleanup\");\n    process.exitCode = 1;\n    return;\n  }\n  throw err;\n}","preventionTips":["Check `which docker` in CI/cron setup steps where PATH is often minimal","Install Docker on every host that may run benchmark cleanup","Use absolute docker path or fix PATH in non-interactive shells","Only invoke the cleanup subcommand on hosts that ran docker-based benchmarks"],"tags":["missing-binary","docker","environment-setup","cleanup"],"backgroundTag":"missing-cli-binary-on-path","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}