gastownhall/beads · error
%q is not an aspect formula (type=%s)
Error message
%q is not an aspect formula (type=%s)
What it means
`bd cook` validates that every formula named in `compose.aspects` actually has `type: aspect`. If the loaded formula's `Type` differs from `formula.TypeAspect`, cook refuses to apply its advice and reports the actual type. This guards against composing with a step-procedure or other non-aspect formula whose advice semantics don't apply.
Source
Thrown at cmd/bd/cook.go:209
// Apply expansion operators
if resolved.Compose != nil && (len(resolved.Compose.Expand) > 0 || len(resolved.Compose.Map) > 0) {
expandedSteps, err := formula.ApplyExpansions(resolved.Steps, resolved.Compose, parser)
if err != nil {
return nil, fmt.Errorf("applying expansions: %w", err)
}
resolved.Steps = expandedSteps
}
// Apply aspects from compose.aspects
if resolved.Compose != nil && len(resolved.Compose.Aspects) > 0 {
for _, aspectName := range resolved.Compose.Aspects {
aspectFormula, err := parser.LoadByName(aspectName)
if err != nil {
return nil, fmt.Errorf("loading aspect %q: %w", aspectName, err)
}
if aspectFormula.Type != formula.TypeAspect {
return nil, fmt.Errorf("%q is not an aspect formula (type=%s)", aspectName, aspectFormula.Type)
}
if len(aspectFormula.Advice) > 0 {
resolved.Steps = formula.ApplyAdvice(resolved.Steps, aspectFormula.Advice)
}
}
}
return resolved, nil
}
// outputCookDryRun displays a dry-run preview of what would be cooked
func outputCookDryRun(resolved *formula.Formula, protoID string, runtimeMode bool, inputVars map[string]string, vars, bondPoints []string) {
modeLabel := "compile-time"
if runtimeMode {
modeLabel = "runtime"
// Apply defaults for runtime mode display
for name, def := range resolved.Vars {
if _, provided := inputVars[name]; !provided && def.Default != nil {View on GitHub (pinned to 71377f2769)
Solutions
- Open the aspect formula file and set `type: aspect` in its front matter
- If the referenced formula is not meant to be an aspect, remove it from `compose.aspects` and reference the correct aspect name
- Run `bd formula validate <name>` (or equivalent) to confirm the type is recognized after editing
Example fix
// before (aspect formula front matter) type: procedure // after type: aspect
Defensive patterns
Strategy: validation
Validate before calling
f, err := parser.LoadByName(name)
if err != nil { return err }
if f.Type != formula.TypeAspect {
return fmt.Errorf("%q has type %s, need aspect", name, f.Type)
} Type guard
func isAspect(f *formula.Formula) bool { return f != nil && f.Type == formula.TypeAspect } Prevention
- Always set `type: aspect` when creating an aspect formula from a template
- Validate formulas (bd formula validate) before referencing them in compose.aspects
- Don't point compose.aspects at main/pipeline formulas
When it happens
Trigger: `compose.aspects` references a formula whose front-matter declares a different type (e.g. `type: procedure`, `type: pipeline`). Loading succeeds, but the type check at cook.go:209 fails.
Common situations: Authoring a new formula and forgetting `type: aspect` in its front matter; pointing `compose.aspects` at a main formula by mistake; copying an aspect but leaving the parent's type value; old formulas written before the type field existed.
Related errors
- applying control flow: %w
- applying expansions: %w
- loading aspect %q: %w
- runtime mode requires all variables to have values Missing:
- formula %q: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/ed6bbef9a50f9f18.
Report an issue: GitHub.