{"record":{"id":"30da4c2f37f798eb","repo":"aaif-goose/goose","slug":"failed-to-parse-github-api-response","errorCode":null,"errorMessage":"Failed to parse GitHub API response: {}","messagePattern":"Failed to parse GitHub API response: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/recipes/github_recipe.rs","lineNumber":271,"sourceCode":"    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\" {\n                    // Check if this directory contains a recipe file\n                    if let Ok(recipe_info) = check_github_directory_for_recipe(repo, name) {\n                        recipes.push(recipe_info);\n                    }\n                }\n            }\n        }\n    }","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/recipes/github_recipe.rs#L253-L289","documentation":"goose parses the stdout of `gh api repos/<repo>/contents` as JSON (crates/goose-cli/src/recipes/github_recipe.rs:270-272). serde_json::from_slice failed, meaning gh exited zero but its stdout was not a valid JSON document — gh debug output, warnings, or a proxy-injected page got mixed into stdout instead of the expected API payload.","triggerScenarios":"GH_DEBUG/GH_DEBUG_API set makes gh print request logs to stdout alongside the body; a wrapper/proxy rewrites the response; gh prints a banner or non-JSON notice (update prompts) to stdout; or truncated output from a killed process.","commonSituations":"Debug env vars left exported in the shell, gh version changes that emit notices, terminals/pagers interfering when output is captured, or HTTPS proxies returning HTML error pages that gh passes through.","solutions":["Run `gh api repos/<owner>/<repo>/contents | head` and inspect what precedes/breaks the JSON; unset GH_DEBUG and GH_DEBUG_API for the goose invocation","Upgrade or pin a known-good gh version if its stdout format changed","Remove any proxy/wrapper that decorates stdout for gh commands"],"exampleFix":"# before\nexport GH_DEBUG=api\nexport GOOSE_RECIPE_GITHUB_REPO=owner/repo\ngoose recipe list\n\n# after\nunset GH_DEBUG GH_DEBUG_API\nexport GOOSE_RECIPE_GITHUB_REPO=owner/repo\ngoose recipe list","handlingStrategy":"validation","validationCode":"# Confirm gh emits pure JSON in this environment\ngh api \"repos/$GOOSE_RECIPE_GITHUB_REPO/contents\" | python3 -c 'import json,sys; json.load(sys.stdin); print(\"valid JSON\")'","typeGuard":null,"tryCatchPattern":"// Rust: on parse failure, include a snippet of the offending stdout\nlet contents: Value = match serde_json::from_slice(&output.stdout) {\n    Ok(v) => v,\n    Err(e) => anyhow::bail!(\n        \"non-JSON gh output ({e}): {}\",\n        String::from_utf8_lossy(&output.stdout[..output.stdout.len().min(200)])\n    ),\n};","preventionTips":["Unset GH_DEBUG/GH_DEBUG_API when invoking tools that parse gh stdout","Pin a known-good gh version in CI images","Avoid proxies/wrappers that decorate stdout of child processes"],"tags":["goose-cli","github-api","json","parsing"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}