{"record":{"id":"78a721a0b42a0735","repo":"zeroclaw-labs/zeroclaw","slug":"cmd-not-found-in-path","errorCode":null,"errorMessage":"{cmd} not found in PATH","messagePattern":"(.+?) not found in PATH","errorType":"console","errorClass":"DiagItem","httpStatus":null,"severity":"warning","filePath":"crates/zeroclaw-runtime/src/doctor/mod.rs","lineNumber":1821,"sourceCode":"        .args(args)\n        .stdout(std::process::Stdio::piped())\n        .stderr(std::process::Stdio::piped())\n        .output()\n    {\n        Ok(output) if output.status.success() => {\n            let ver = String::from_utf8_lossy(&output.stdout);\n            let first_line = ver.lines().next().unwrap_or(\"\").trim();\n            let display = truncate_for_display(first_line, COMMAND_VERSION_PREVIEW_CHARS);\n            items.push(DiagItem::ok(cat, format!(\"{cmd}: {display}\")));\n        }\n        Ok(_) => {\n            items.push(DiagItem::warn(\n                cat,\n                format!(\"{cmd} found but returned non-zero\"),\n            ));\n        }\n        Err(_) => {\n            items.push(DiagItem::warn(cat, format!(\"{cmd} not found in PATH\")));\n        }\n    }\n}\n\nfn format_error_chain(error: &anyhow::Error) -> String {\n    let mut parts = Vec::new();\n    for cause in error.chain() {\n        let message = cause.to_string();\n        if !message.is_empty() {\n            parts.push(message);\n        }\n    }\n\n    if parts.is_empty() {\n        return String::new();\n    }\n\n    parts.join(\": \")","sourceCodeStart":1803,"sourceCodeEnd":1839,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/doctor/mod.rs#L1803-L1839","documentation":"A `zeroclaw doctor` warning from `check_command_available`: spawning the probed command (`git` or `curl`) failed at the OS level — classically `ErrorKind::NotFound`, meaning the binary is not on PATH. Doctor probes these because several features (workspace tooling, HTTP fallbacks) depend on them being usable.","triggerScenarios":"Running `zeroclaw doctor` when `git` or `curl` is not installed, or is installed outside the PATH visible to doctor — common in minimal containers, clean-room servers, and systemd units with a restricted PATH.","commonSituations":"Slim Docker images (no build tools); hardened VMs; macOS/Linux servers where Xcode CLT or curl is missing; service units whose PATH lacks `/usr/bin`.","solutions":["Install the missing tool: `apt-get install -y git curl` (or the platform equivalent).","If it is installed, extend PATH for the context doctor runs in (unit `Environment=PATH=...`, container ENV, shell profile).","Re-run `zeroclaw doctor` and confirm the `<cmd>: <version>` ok line."],"exampleFix":"# before: doctor -> \"git not found in PATH\"\n\n# after (Debian/Ubuntu)\napt-get update && apt-get install -y git curl","handlingStrategy":"validation","validationCode":"fn on_path(cmd: &str) -> bool {\n    std::process::Command::new(cmd).arg(\"--version\")\n        .stdout(std::process::Stdio::null())\n        .stderr(std::process::Stdio::null())\n        .output()\n        .is_ok()\n}\n\nfor cmd in [\"git\", \"curl\"] {\n    assert!(on_path(cmd), \"{cmd} not found in PATH\");\n}","typeGuard":"fn command_on_path(cmd: &str) -> bool {\n    std::process::Command::new(cmd).arg(\"--version\").output().is_ok()\n}","tryCatchPattern":null,"preventionTips":["Install git and curl in base images rather than assuming they exist.","Pin an explicit PATH in service units and containers so spawn-not-found cannot happen at runtime."],"tags":["environment","path","git","curl","doctor","zeroclaw"],"backgroundTag":"tool-not-in-path","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}