aaif-goose/goose · error
Failed to access directory: {}
Error message
Failed to access directory: {} What it means
check_github_directory_for_recipe treats a non-zero exit of `gh api repos/<repo>/contents/<dir>` as this error, naming the directory that failed (crates/goose-cli/src/recipes/github_recipe.rs:305-307). gh's stderr with the concrete HTTP reason appears above it. Common causes: the directory does not exist (repo changed since the parent listing), is a file not a dir, no access, or rate limiting during discovery.
Source
Thrown at crates/goose-cli/src/recipes/github_recipe.rs:306
}
}
Ok(recipes)
}
fn check_github_directory_for_recipe(repo: &str, dir_name: &str) -> Result<RecipeInfo> {
use serde_json::Value;
use std::process::Command;
// Check directory contents for recipe files
let output = Command::new("gh")
.args(["api", &format!("repos/{}/contents/{}", repo, dir_name)])
.set_no_window()
.output()
.map_err(|e| anyhow!("Failed to check directory contents: {}", e))?;
if !output.status.success() {
return Err(anyhow!("Failed to access directory: {}", dir_name));
}
let contents: Value = serde_json::from_slice(&output.stdout)
.map_err(|e| anyhow!("Failed to parse directory contents: {}", e))?;
if let Some(items) = contents.as_array() {
for item in items {
if let Some(name) = item.get("name").and_then(|n| n.as_str()) {
if RECIPE_FILE_EXTENSIONS
.iter()
.any(|ext| name == format!("recipe.{}", ext))
{
// Found a recipe file, get its content
return get_github_recipe_info(repo, dir_name, name);
}
}
}
}View on GitHub (pinned to 3810898a74)
Solutions
- Check the directory manually: `gh api repos/<owner>/<repo>/contents/<dir-name>` — the returned status explains whether it is 404, 403, or encoding-related
- Rename repo directories to URL-safe names (lowercase, hyphens) if special characters are involved
- If rate-limited during discovery of a large repo, wait for reset or authenticate with a higher-limit token; re-run after the repo layout settles
Defensive patterns
Strategy: try-catch
Validate before calling
# Validate each candidate directory is API-addressable before discovery gh repo view "$GOOSE_RECIPE_GITHUB_REPO" --json name >/dev/null gh api "repos/$GOOSE_RECIPE_GITHUB_REPO/contents" --jq '.[] | select(.type=="dir") | .name' \ | while read -r d; do gh api "repos/$GOOSE_RECIPE_GITHUB_REPO/contents/$d" >/dev/null || echo "bad dir: $d"; done
Try / catch
// Rust: skip directories that fail to probe instead of aborting all discovery
match check_github_directory_for_recipe(repo, name) {
Ok(info) => recipes.push(info),
Err(e) => tracing::warn!("skipping directory {name}: {e}"),
} Prevention
- Use URL-safe directory names (lowercase, hyphens, no spaces/#) in recipe repos
- Avoid editing the recipe repo layout while discovery runs
- Watch rate limits when probing many directories; cache or batch where possible
When it happens
Trigger: Repo layout changes between the contents listing and the per-directory probe; symlinks/submodules the API lists but cannot enumerate; private/protected paths the token cannot read; secondary rate limits when probing many directories quickly.
Common situations: Recipe repo being edited while goose lists it, large repos triggering GitHub rate limits during discovery, or names with characters needing URL encoding (spaces, '#') that break the naive path concatenation in the API URL.
Related errors
- GitHub API request failed: {}
- Could not retrieve sub-recipe '{}': {}
- Unknown error occurred
- No recipe file found in {} (looked for extensions: {:?})
- Failed to parse GitHub API response: {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/3f31024167688e9e.
Report an issue: GitHub.