{"record":{"id":"f4e47a643e7dfec3","repo":"gastownhall/beads","slug":"recipe-q-has-no-file-contents","errorCode":null,"errorMessage":"recipe %q has no file contents","messagePattern":"recipe %q has no file contents","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/recipes/template.go","lineNumber":100,"sourceCode":"## Context Loading\n\nRun ` + \"`bd prime`\" + ` for the full workflow context.\n\nIf the Beads Copilot plugin is installed, Copilot CLI will automatically run\n` + \"`bd prime`\" + ` on session start and before compaction.\n`\n\n// ContentForPath returns the file content that should be written for a recipe path.\nfunc ContentForPath(recipe Recipe, path string) (string, error) {\n\tswitch recipe.Type {\n\tcase TypeFile:\n\t\tif recipe.Content != \"\" {\n\t\t\treturn recipe.Content, nil\n\t\t}\n\t\treturn Template, nil\n\tcase TypeMultiFile:\n\t\tif len(recipe.Contents) == 0 {\n\t\t\treturn \"\", fmt.Errorf(\"recipe %q has no file contents\", recipe.Name)\n\t\t}\n\t\tcontent, ok := recipe.Contents[path]\n\t\tif !ok {\n\t\t\treturn \"\", fmt.Errorf(\"recipe %q has no content for %s\", recipe.Name, path)\n\t\t}\n\t\treturn content, nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"recipe %q has unsupported type %q\", recipe.Name, recipe.Type)\n\t}\n}\n","sourceCodeStart":82,"sourceCodeEnd":111,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/recipes/template.go#L82-L111","documentation":"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.","triggerScenarios":"A user-defined recipe in recipes.toml sets type=\"multifile\" (TypeMultiFile) but supplies no [recipes.<name>.contents] entries; ContentForPath then finds len(Contents)==0.","commonSituations":"Hand-writing a multi-file recipe but forgetting the contents table, or defining contents under the wrong key so Unmarshal leaves the map empty.","solutions":["Add a [recipes.<name>.contents] table with an entry for the requested path","Verify the TOML keys nest correctly so toml.Unmarshal populates Contents","If the recipe should be single-file, set type=\"file\" and provide content instead","Run the recipe validate/list command to inspect how the recipe was loaded"],"exampleFix":"// before\n[recipes.myrecipe]\ntype = \"multifile\"\n// after\n[recipes.myrecipe]\ntype = \"multifile\"\n[recipes.myrecipe.contents]\n\"AGENTS.md\" = \"...template text...\"","handlingStrategy":"validation","validationCode":"func validateRecipe(r Recipe) error {\n\tif r.Type == TypeMultiFile && len(r.Contents) == 0 {\n\t\treturn fmt.Errorf(\"recipe %q is multifile but has no contents\", r.Name)\n\t}\n\treturn nil\n}","typeGuard":"func isUsableMultiFileRecipe(r Recipe, path string) bool {\n\treturn r.Type == TypeMultiFile && len(r.Contents) > 0 && r.Contents[path] != \"\"\n}","tryCatchPattern":"content, err := recipes.ContentForPath(ctx, recipe, path)\nif err != nil {\n\tif strings.Contains(err.Error(), \"has no file contents\") {\n\t\treturn fmt.Errorf(\"recipe %s is misconfigured: add [recipes.%s.contents] in recipes.toml\", recipe.Name, recipe.Name)\n\t}\n\treturn err\n}","preventionTips":["Always define [recipes.<name>.contents] for multifile recipes","Verify nested TOML tables so Contents actually unmarshals","Use `file` type with `content` for single-file recipes","Validate user recipes right after editing recipes.toml"],"tags":["recipes","template","config","validation"],"backgroundTag":"missing-template-content","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}