{"record":{"id":"1d1e214f84169dd7","repo":"aaif-goose/goose","slug":"failed-to-clone-repo","errorCode":null,"errorMessage":"Failed to clone repo: {}","messagePattern":"Failed to clone repo: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/recipes/github_recipe.rs","lineNumber":181,"sourceCode":"\nfn ensure_repo_cloned(recipe_repo_full_name: &str) -> Result<PathBuf> {\n    let local_repo_parent_path = env::temp_dir();\n    if !local_repo_parent_path.exists() {\n        std::fs::create_dir_all(local_repo_parent_path.clone())?;\n    }\n    let local_repo_path = get_local_repo_path(&local_repo_parent_path, recipe_repo_full_name)?;\n\n    if local_repo_path.join(\".git\").exists() {\n        Ok(local_repo_path)\n    } else {\n        let error_message: String = format!(\"Failed to clone repo: {}\", recipe_repo_full_name);\n        let status = Command::new(\"gh\")\n            .args([\"repo\", \"clone\", recipe_repo_full_name])\n            .arg(&local_repo_path)\n            .current_dir(local_repo_parent_path.clone())\n            .set_no_window()\n            .status()\n            .map_err(|_: std::io::Error| anyhow::anyhow!(error_message.clone()))?;\n\n        if status.success() {\n            Ok(local_repo_path)\n        } else {\n            Err(anyhow::anyhow!(error_message))\n        }\n    }\n}\n\nfn fetch_origin(local_repo_path: &Path) -> Result<()> {\n    let error_message: String = format!(\"Failed to fetch at {}\", local_repo_path.to_str().unwrap());\n    let status = git_command()\n        .args([\"fetch\", \"origin\"])\n        .current_dir(local_repo_path)\n        .set_no_window()\n        .status()\n        .map_err(|_| anyhow::anyhow!(error_message.clone()))?;\n","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/recipes/github_recipe.rs#L163-L199","documentation":"ensure_repo_cloned runs `gh repo clone <owner/repo> <dest>` when the destination has no .git directory (crates/goose-cli/src/recipes/github_recipe.rs:176-187). The first failure mode is the spawn itself returning an io::Error, which is mapped to this message with the repo name. Like [126], it means the gh process never ran — not that the clone failed.","triggerScenarios":"Command::new(\"gh\").status() io failure at clone time: gh missing from PATH at this moment (it existed for the earlier auth check), exec format/permission error, or fork failure (EAGAIN) under resource pressure. Note this branch uses `gh`, not `git`.","commonSituations":"PATH mutated between goose startup and clone (shell wrapper, direnv hook), gh being upgraded/replaced concurrently, or a recipe run inside a container where gh is present but execution is denied by seccomp/AppArmor.","solutions":["Verify gh resolves and runs in the exact execution context: `command -v gh && gh repo view owner/repo`","If gh was never installed, install it (see [126]) — the auth check error would normally fire first, so a hit here suggests an environment change mid-run","For sandboxed runners, allow exec of the gh binary in the sandbox profile"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Ensure gh exists and can see the repo before invoking goose\ncommand -v gh && gh repo view \"$GOOSE_RECIPE_GITHUB_REPO\" >/dev/null \\\n  && echo \"clone preconditions OK\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep gh installed and on PATH for the entire goose process lifetime","Verify with `gh repo view owner/repo` that access works before recipe runs"],"tags":["goose-cli","github-cli","git-clone","external-tool"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}