gastownhall/beads · error
unknown recipe: %s
Error message
unknown recipe: %s
What it means
GetRecipe was asked for a recipe name that exists neither in the built-in recipes nor in the user's recipes.toml. There is no default/fuzzy matching — the exact name must exist.
Source
Thrown at internal/recipes/recipes.go:210
result[name] = recipe
}
return result, nil
}
// GetRecipe looks up a recipe by name, checking user recipes first.
func GetRecipe(name string, beadsDir string) (*Recipe, error) {
// Normalize name (lowercase, strip leading/trailing hyphens)
name = strings.ToLower(strings.Trim(name, "-"))
recipes, err := GetAllRecipes(beadsDir)
if err != nil {
return nil, err
}
recipe, ok := recipes[name]
if !ok {
return nil, fmt.Errorf("unknown recipe: %s", name)
}
return &recipe, nil
}
// SaveUserRecipe adds or updates a recipe in .beads/recipes.toml.
func SaveUserRecipe(beadsDir, name, path string) error {
recipesPath := filepath.Join(beadsDir, "recipes.toml")
// Load existing user recipes
var userRecipes UserRecipes
data, err := os.ReadFile(recipesPath) // #nosec G304 -- path is constructed from validated beadsDir
if err == nil {
if err := toml.Unmarshal(data, &userRecipes); err != nil {
return fmt.Errorf("parse recipes.toml: %w", err)
}
} else if !os.IsNotExist(err) {
return fmt.Errorf("read recipes.toml: %w", err)View on GitHub (pinned to 71377f2769)
Solutions
- List available recipes (ListRecipeNames / the recipes list command) and use an exact existing name
- Check that .beads/recipes.toml actually defines the recipe under [recipes.<name>]
- Fix typos or case differences in the requested name
- If a recipe was renamed in an upgrade, update scripts/docs to the new name
Example fix
// before recipe, err := recipes.GetRecipe(ctx, "setup-copilot") // after recipe, err := recipes.GetRecipe(ctx, "copilot")
Defensive patterns
Strategy: fallback
Validate before calling
names, err := recipes.ListRecipeNames(ctx, beadsDir)
if !slices.Contains(names, wanted) {
return fmt.Errorf("recipe %q not found; available: %v", wanted, names)
} Try / catch
r, err := GetRecipe(ctx, name)
if err != nil {
if strings.HasPrefix(err.Error(), "unknown recipe") {
// suggest closest match
suggestClosest(name, knownNames)
return nil
}
return err
} Prevention
- Discover valid names with ListRecipeNames before lookup
- Copy recipe names exactly (watch case and dashes)
- Verify user recipes load successfully (no parse errors) before relying on them
- After upgrading, re-check for renamed recipes in release notes
When it happens
Trigger: Calling GetRecipe(name) (or the CLI command that uses it) with a name not present in the merged recipe map.
Common situations: Typos in the recipe name, a user recipe that failed to load (so only built-ins are visible), referencing a recipe deleted from recipes.toml, or following docs for a recipe renamed in a newer version.
Related errors
- resolving ID %s: no issue found matching %q
- resolving --deps target %q: %w
- parent issue %s not found
- resolving issue ID %q: %w
- step %s not found
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/a735d983c356baf5.
Report an issue: GitHub.