aaif-goose/goose · error

No recipe file found in directory: {}

Error message

No recipe file found in directory: {}

What it means

The directory listing from GitHub succeeded and parsed, but no entry matched a file named exactly `recipe.yaml` or `recipe.json` (goose::recipe::RECIPE_FILE_EXTENSIONS is &["yaml", "json"]). Goose requires every recipe directory in a repo to contain one of those exact filenames. Notably `recipe.yml` does NOT match.

Source

Thrown at crates/goose-cli/src/recipes/github_recipe.rs:326

    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);
                }
            }
        }
    }

    Err(anyhow!("No recipe file found in directory: {}", dir_name))
}

fn get_github_recipe_info(repo: &str, dir_name: &str, recipe_filename: &str) -> Result<RecipeInfo> {
    use serde_json::Value;
    use std::process::Command;

    // Get the recipe file content
    let output = Command::new("gh")
        .args([
            "api",
            &format!("repos/{}/contents/{}/{}", repo, dir_name, recipe_filename),
        ])
        .set_no_window()
        .output()
        .map_err(|e| anyhow!("Failed to get recipe file content: {}", e))?;

    if !output.status.success() {
        return Err(anyhow!(

View on GitHub (pinned to 3810898a74)

Solutions

  1. Check the directory contents via `gh api repos/{repo}/contents/{dir_name}` and look for a file literally named recipe.yaml or recipe.json.
  2. If the file is recipe.yml, rename it to recipe.yaml in the upstream repo.
  3. Verify exact casing and that no subdirectory nesting moved the recipe file.

Example fix

# before (directory listing):
# [{"name": "recipe.yml"}, {"name": "README.md"}]
# -> Err: No recipe file found in directory: my-recipe

# after
git mv my-recipe/recipe.yml my-recipe/recipe.yaml
git commit -m "rename recipe file to recipe.yaml" && git push
Defensive patterns

Strategy: validation

Validate before calling

# verify the exact filename exists before goose scans it
gh api "repos/${REPO}/contents/${DIR}" --jq '.[].name' | grep -Ex 'recipe.(yaml|json)' \
  || echo "missing recipe.yaml/recipe.json in ${DIR}"

Try / catch

match list_recipe_dir(repo, dir) {
    Err(e) if e.to_string().contains("No recipe file found") => {
        // directory exists but is not a recipe; skip or fix upstream
        skip(dir);
    }
    other => other,
}

Prevention

When it happens

Trigger: Loading a GitHub recipe whose subdirectory exists but contains a file named differently: `recipe.yml` instead of `recipe.yaml`, `Recipe.yaml` (case mismatch), or only a README / other files.

Common situations: Recipe authors naming the file recipe.yml out of habit (the .yml extension is not accepted here); renamed files in the upstream repo; a directory that is not actually a recipe but sits in the scanned path.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/bfbb3870bcb01a07. Report an issue: GitHub.