{"record":{"id":"1dcd4f06b3e02c4e","repo":"aaif-goose/goose","slug":"failed-to-get-recipe-file-content","errorCode":null,"errorMessage":"Failed to get recipe file content: {}","messagePattern":"Failed to get recipe file content: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/recipes/github_recipe.rs","lineNumber":341,"sourceCode":"        }\n    }\n\n    Err(anyhow!(\"No recipe file found in directory: {}\", dir_name))\n}\n\nfn get_github_recipe_info(repo: &str, dir_name: &str, recipe_filename: &str) -> Result<RecipeInfo> {\n    use serde_json::Value;\n    use std::process::Command;\n\n    // Get the recipe file content\n    let output = Command::new(\"gh\")\n        .args([\n            \"api\",\n            &format!(\"repos/{}/contents/{}/{}\", repo, dir_name, recipe_filename),\n        ])\n        .set_no_window()\n        .output()\n        .map_err(|e| anyhow!(\"Failed to get recipe file content: {}\", e))?;\n\n    if !output.status.success() {\n        return Err(anyhow!(\n            \"Failed to access recipe file: {}/{}\",\n            dir_name,\n            recipe_filename\n        ));\n    }\n\n    let file_info: Value = serde_json::from_slice(&output.stdout)\n        .map_err(|e| anyhow!(\"Failed to parse file info: {}\", e))?;\n\n    if let Some(content_b64) = file_info.get(\"content\").and_then(|c| c.as_str()) {\n        // Decode base64 content\n        use base64::{engine::general_purpose, Engine as _};\n        let content_bytes = general_purpose::STANDARD\n            .decode(content_b64.replace('\\n', \"\"))\n            .map_err(|e| anyhow!(\"Failed to decode base64 content: {}\", e))?;","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/recipes/github_recipe.rs#L323-L359","documentation":"std::process::Command::new(\"gh\").output() itself failed at the OS level when fetching an individual recipe file — the gh executable could not be spawned. This is not an HTTP error; it means the process never ran, almost always because `gh` is not on PATH in the environment goose runs in.","triggerScenarios":"Executing goose recipe loading in a shell/container/GUI-launched process whose PATH does not include the GitHub CLI binary; gh installed via a method (e.g. hermit) not activated in the current shell.","commonSituations":"Fresh machines without gh installed; running goose from a desktop app or systemd service with a minimal PATH; container images missing the gh package; forgetting to `source bin/activate-hermit` in the goose repo.","solutions":["Verify with `which gh`; if missing, install it (brew install gh / apt install gh) or activate the environment that provides it.","If launching goose from a GUI or service, ensure PATH includes gh's install location (e.g. /usr/local/bin, /opt/homebrew/bin).","Re-run the goose command from a shell where `gh --version` works."],"exampleFix":"# before\n$ goose recipe info owner/repo/my-recipe\nError: Failed to get recipe file content: No such file or directory (os error 2)\n\n# after\n$ brew install gh   # or: apt install gh\n$ which gh && gh --version\n$ goose recipe info owner/repo/my-recipe","handlingStrategy":"validation","validationCode":"use std::process::Command;\nfn gh_available() -> bool {\n    Command::new(\"gh\").arg(\"--version\").output().map(|o| o.status.success()).unwrap_or(false)\n}\n// call gh_available() before any recipe-from-GitHub flow","typeGuard":null,"tryCatchPattern":"match run() {\n    Err(e) if e.to_string().contains(\"Failed to get recipe file content\") => {\n        eprintln!(\"gh CLI not spawnable — install gh or fix PATH\");\n    }\n    r => r,\n}","preventionTips":["Install gh and verify `which gh` in every environment that loads GitHub recipes.","When launching goose from GUIs/services, inherit a PATH that includes gh.","Document the gh dependency in setup scripts."],"tags":["gh-cli","process-spawn","path","recipes","environment"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}