{"record":{"id":"899a9d471ef92ff6","repo":"zeroclaw-labs/zeroclaw","slug":"git-clone-failed-stderr","errorCode":null,"errorMessage":"Git clone failed: {stderr}","messagePattern":"Git clone failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/zeroclaw-runtime/src/skills/mod.rs","lineNumber":2131,"sourceCode":"            let _ = std::fs::remove_dir_all(&dest);\n            Err(err)\n        }\n    }\n}\n\npub fn install_git_skill_source(\n    source: &str,\n    skills_path: &Path,\n    allow_scripts: bool,\n) -> Result<(PathBuf, usize)> {\n    let before = snapshot_skill_children(skills_path)?;\n    let output = std::process::Command::new(\"git\")\n        .args([\"clone\", \"--depth\", \"1\", source])\n        .current_dir(skills_path)\n        .output()?;\n    if !output.status.success() {\n        let stderr = String::from_utf8_lossy(&output.stderr);\n        anyhow::bail!(\"Git clone failed: {stderr}\");\n    }\n\n    let installed_dir = detect_newly_installed_directory(skills_path, &before)?;\n    remove_git_metadata(&installed_dir)?;\n    match enforce_skill_security_audit(&installed_dir, allow_scripts) {\n        Ok(report) => Ok((installed_dir, report.files_scanned)),\n        Err(err) => {\n            let _ = std::fs::remove_dir_all(&installed_dir);\n            Err(err)\n        }\n    }\n}\n\n// ─── Skills registry resolution ───────────────────────────────────────────────\n\npub fn is_registry_source(source: &str) -> bool {\n    if source.is_empty() {\n        return false;","sourceCodeStart":2113,"sourceCodeEnd":2149,"githubUrl":"https://github.com/zeroclaw-labs/zeroclaw/blob/88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc/crates/zeroclaw-runtime/src/skills/mod.rs#L2113-L2149","documentation":"install_git_skill_source shells out to 'git clone --depth 1 <source>' inside the skills directory; git exited non-zero and its raw stderr is embedded in the message. The failure is git's own — unreachable host, repository not found, authentication required, proxy refusal — surfaced verbatim.","triggerScenarios":"404 repo URL; private repository without credentials; DNS/network failure; misconfigured proxy; servers that reject shallow clones (--depth 1).","commonSituations":"Corporate proxies blocking the git host; typo'd git URL; SSH remote without keys; HTTPS remote requiring a PAT; air-gapped machines.","solutions":["Run 'git clone --depth 1 <url>' manually to see the exact git failure","Fix the URL or credentials (SSH keys, personal access token, or switch to HTTPS)","Verify network/proxy reachability of the git host from this machine","If the server cannot serve shallow clones, host or point at a mirror that can"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Cheap pre-flight: the remote must at least be reachable\nlet ok = std::process::Command::new(\"git\")\n    .args([\"ls-remote\", \"--exit-code\", source])\n    .output()\n    .map(|o| o.status.success())\n    .unwrap_or(false);\nif !ok {\n    anyhow::bail!(\"git cannot reach {source}; check URL, credentials, network\");\n}","typeGuard":null,"tryCatchPattern":"match install_git_skill_source(url, &skills_path, allow_scripts) {\n    Err(e) if e.to_string().starts_with(\"Git clone failed:\") => {\n        // the remainder is git's own stderr: surface it, check URL/auth/proxy,\n        // optionally retry once for transient network failures\n    }\n    r => r,\n}","preventionTips":["Run 'git clone --depth 1 <url>' manually once before automating installs","Ensure credentials (SSH keys/PAT) are configured for private repos","Confirm proxies and egress allow the git host; shallow-clone support is required (--depth 1)"],"tags":["skills","install","git","network"],"backgroundTag":"git-clone-failed","analyzedSha":"88bb9c8533fc57ed7a03e36ca7c9ed2bf8336dcc","analyzedAt":"2026-08-23T01:07:41.857Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}