gastownhall/beads · error

recipe %q has no file contents

Error message

recipe %q has no file contents

What it means

ContentForPath was called for a multi-file recipe (TypeMultiFile) whose Contents map is empty, so there is no template content to return for the requested path. Multi-file recipes must populate Contents with at least the target path.

Source

Thrown at internal/recipes/template.go:100

## Context Loading

Run ` + "`bd prime`" + ` for the full workflow context.

If the Beads Copilot plugin is installed, Copilot CLI will automatically run
` + "`bd prime`" + ` on session start and before compaction.
`

// ContentForPath returns the file content that should be written for a recipe path.
func ContentForPath(recipe Recipe, path string) (string, error) {
	switch recipe.Type {
	case TypeFile:
		if recipe.Content != "" {
			return recipe.Content, nil
		}
		return Template, nil
	case TypeMultiFile:
		if len(recipe.Contents) == 0 {
			return "", fmt.Errorf("recipe %q has no file contents", recipe.Name)
		}
		content, ok := recipe.Contents[path]
		if !ok {
			return "", fmt.Errorf("recipe %q has no content for %s", recipe.Name, path)
		}
		return content, nil
	default:
		return "", fmt.Errorf("recipe %q has unsupported type %q", recipe.Name, recipe.Type)
	}
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Add a [recipes.<name>.contents] table with an entry for the requested path
  2. Verify the TOML keys nest correctly so toml.Unmarshal populates Contents
  3. If the recipe should be single-file, set type="file" and provide content instead
  4. Run the recipe validate/list command to inspect how the recipe was loaded

Example fix

// before
[recipes.myrecipe]
type = "multifile"
// after
[recipes.myrecipe]
type = "multifile"
[recipes.myrecipe.contents]
"AGENTS.md" = "...template text..."
Defensive patterns

Strategy: validation

Validate before calling

func validateRecipe(r Recipe) error {
	if r.Type == TypeMultiFile && len(r.Contents) == 0 {
		return fmt.Errorf("recipe %q is multifile but has no contents", r.Name)
	}
	return nil
}

Type guard

func isUsableMultiFileRecipe(r Recipe, path string) bool {
	return r.Type == TypeMultiFile && len(r.Contents) > 0 && r.Contents[path] != ""
}

Try / catch

content, err := recipes.ContentForPath(ctx, recipe, path)
if err != nil {
	if strings.Contains(err.Error(), "has no file contents") {
		return fmt.Errorf("recipe %s is misconfigured: add [recipes.%s.contents] in recipes.toml", recipe.Name, recipe.Name)
	}
	return err
}

Prevention

When it happens

Trigger: A user-defined recipe in recipes.toml sets type="multifile" (TypeMultiFile) but supplies no [recipes.<name>.contents] entries; ContentForPath then finds len(Contents)==0.

Common situations: Hand-writing a multi-file recipe but forgetting the contents table, or defining contents under the wrong key so Unmarshal leaves the map empty.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/f4e47a643e7dfec3. Report an issue: GitHub.