{"record":{"id":"0c528dc078eac4ff","repo":"aaif-goose/goose","slug":"failed-to-fetch-repository-contents-using-gh-api","errorCode":null,"errorMessage":"Failed to fetch repository contents using 'gh api' command (executed when GOOSE_RECIPE_GITHUB_REPO is configured). This requires GitHub CLI (gh) to be installed and authenticated. Error: {}","messagePattern":"Failed to fetch repository contents using 'gh api' command \\(executed when GOOSE_RECIPE_GITHUB_REPO is configured\\)\\. This requires GitHub CLI \\(gh\\) to be installed and authenticated\\. Error: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/recipes/github_recipe.rs","lineNumber":263,"sourceCode":"\n/// Lists all available recipes from a GitHub repository\npub fn list_github_recipes(repo: &str) -> Result<Vec<RecipeInfo>> {\n    discover_github_recipes(repo)\n}\n\nfn discover_github_recipes(repo: &str) -> Result<Vec<RecipeInfo>> {\n    use serde_json::Value;\n    use std::process::Command;\n\n    // Ensure GitHub CLI is authenticated\n    ensure_gh_authenticated()?;\n\n    // Get repository contents using GitHub CLI\n    let output = Command::new(\"gh\")\n        .args([\"api\", &format!(\"repos/{}/contents\", repo)])\n        .set_no_window()\n        .output()\n        .map_err(|e| anyhow!(\"Failed to fetch repository contents using 'gh api' command (executed when GOOSE_RECIPE_GITHUB_REPO is configured). This requires GitHub CLI (gh) to be installed and authenticated. Error: {}\", e))?;\n\n    if !output.status.success() {\n        let error_msg = String::from_utf8_lossy(&output.stderr);\n        return Err(anyhow!(\"GitHub API request failed: {}\", error_msg));\n    }\n\n    let contents: Value = serde_json::from_slice(&output.stdout)\n        .map_err(|e| anyhow!(\"Failed to parse GitHub API response: {}\", e))?;\n\n    let mut recipes = Vec::new();\n\n    if let Some(items) = contents.as_array() {\n        for item in items {\n            if let (Some(name), Some(item_type)) = (\n                item.get(\"name\").and_then(|n| n.as_str()),\n                item.get(\"type\").and_then(|t| t.as_str()),\n            ) {\n                if item_type == \"dir\" {","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/recipes/github_recipe.rs#L245-L281","documentation":"discover_github_recipes lists available recipes by running `gh api repos/<repo>/contents` (crates/goose-cli/src/recipes/github_recipe.rs:250-263). This error is the spawn io failure of that command, mapped to a message explaining it requires the GitHub CLI installed and authenticated. It fires after ensure_gh_authenticated() succeeded, so in practice gh existed moments earlier.","triggerScenarios":"Command::new(\"gh\").output() io error: gh not on PATH (would normally be caught earlier by the auth check), binary replaced/removed between the auth check and this call, exec permission/format error, or resource exhaustion at spawn.","commonSituations":"Same class as [126] but on the discovery path (`goose recipe list` style flows with GOOSE_RECIPE_GITHUB_REPO set): missing gh on minimal systems, PATH drift in wrappers, or concurrent brew/winget upgrades swapping the gh binary mid-run.","solutions":["Install/repair GitHub CLI and confirm `command -v gh && gh api repos/<owner>/<repo>/contents` works in goose's shell","Check PATH stability of the environment (CI steps that strip PATH, direnv hooks) so gh stays resolvable for the whole goose invocation","Re-run the command; a transient spawn failure (EAGAIN) clears when resource pressure drops"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"# Exercise the exact API call goose will make\ngh api \"repos/$GOOSE_RECIPE_GITHUB_REPO/contents\" >/dev/null && echo \"gh api OK\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install and authenticate gh before using GitHub-backed recipe discovery","Keep PATH stable across the whole goose invocation (avoid mid-run env swaps)"],"tags":["goose-cli","github-cli","api","external-tool"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}