aaif-goose/goose · error
Failed to clone repo: {}
Error message
Failed to clone repo: {} What it means
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.
Source
Thrown at crates/goose-cli/src/recipes/github_recipe.rs:181
fn ensure_repo_cloned(recipe_repo_full_name: &str) -> Result<PathBuf> {
let local_repo_parent_path = env::temp_dir();
if !local_repo_parent_path.exists() {
std::fs::create_dir_all(local_repo_parent_path.clone())?;
}
let local_repo_path = get_local_repo_path(&local_repo_parent_path, recipe_repo_full_name)?;
if local_repo_path.join(".git").exists() {
Ok(local_repo_path)
} else {
let error_message: String = format!("Failed to clone repo: {}", recipe_repo_full_name);
let status = Command::new("gh")
.args(["repo", "clone", recipe_repo_full_name])
.arg(&local_repo_path)
.current_dir(local_repo_parent_path.clone())
.set_no_window()
.status()
.map_err(|_: std::io::Error| anyhow::anyhow!(error_message.clone()))?;
if status.success() {
Ok(local_repo_path)
} else {
Err(anyhow::anyhow!(error_message))
}
}
}
fn fetch_origin(local_repo_path: &Path) -> Result<()> {
let error_message: String = format!("Failed to fetch at {}", local_repo_path.to_str().unwrap());
let status = git_command()
.args(["fetch", "origin"])
.current_dir(local_repo_path)
.set_no_window()
.status()
.map_err(|_| anyhow::anyhow!(error_message.clone()))?;
View on GitHub (pinned to 3810898a74)
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
Defensive patterns
Strategy: validation
Validate before calling
# Ensure gh exists and can see the repo before invoking goose command -v gh && gh repo view "$GOOSE_RECIPE_GITHUB_REPO" >/dev/null \ && echo "clone preconditions OK"
Prevention
- 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
When it happens
Trigger: 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`.
Common situations: 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.
Related errors
- Failed to run `gh auth status`. Make sure you have `gh` inst
- Failed to run `gh auth login`
- Failed to fetch repository contents using 'gh api' command (
- Failed to check directory contents: {}
- Failed to authenticate using GitHub CLI.
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/1d1e214f84169dd7.
Report an issue: GitHub.