gastownhall/beads · error
applying expansions: %w
Error message
applying expansions: %w
What it means
cmd/bd/cook.go:196 wraps errors from formula.ApplyExpansions(resolved.Steps, resolved.Compose, parser), which processes compose-level expansion operators (compose.expand and compose.map) to fan steps out over collections or substitute them. It only runs when Compose declares expand/map entries; failure means one of those operators is malformed or references something unresolvable (bad expression, missing target formula, invalid map key).
Source
Thrown at cmd/bd/cook.go:196
resolved.Steps = controlFlowSteps
// Apply advice transformations
if len(resolved.Advice) > 0 {
resolved.Steps = formula.ApplyAdvice(resolved.Steps, resolved.Advice)
}
// Apply inline step expansions
inlineExpandedSteps, err := formula.ApplyInlineExpansions(resolved.Steps, parser)
if err != nil {
return nil, fmt.Errorf("applying inline expansions: %w", err)
}
resolved.Steps = inlineExpandedSteps
// 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)
}
}View on GitHub (pinned to 71377f2769)
Solutions
- Inspect compose.expand/compose.map in the formula and compare each entry's expression and targets against the wrapped error message.
- Verify every expand target formula exists in the registry and parses standalone.
- Confirm map keys match parameters actually declared/used by the expanded steps.
- Simplify to a single expand/map entry and re-run to isolate the failing operator.
Example fix
// before (compose block) expand: - formula: matrix-run # never defined // after expand: - formula: run-per-env # exists in .beads/formulas/
Defensive patterns
Strategy: validation
Validate before calling
func expansionsResolvable(c *formula.ComposeRules, load func(string) (*formula.Formula, error)) error {
if c == nil {
return nil
}
for _, e := range c.Expand {
if _, err := load(e.Formula); err != nil {
return fmt.Errorf("expand target %q unloadable: %w", e.Formula, err)
}
}
for _, m := range c.Map {
if m.Formula != "" {
if _, err := load(m.Formula); err != nil {
return fmt.Errorf("map target %q unloadable: %w", m.Formula, err)
}
}
}
return nil
} Type guard
func hasValidExpansions(c *formula.ComposeRules, exists func(string) bool) bool {
if c == nil {
return true
}
for _, e := range c.Expand {
if !exists(e.Formula) {
return false
}
}
return true
} Try / catch
expanded, err := formula.ApplyExpansions(resolved.Steps, resolved.Compose, parser)
if err != nil {
return fmt.Errorf("compose expand/map is invalid: %w", err)
} Prevention
- Ensure every compose.expand/compose.map target formula exists and parses in the target environment.
- Keep map keys in sync with parameters the expanded formula actually declares.
- Test expansions with a minimal collection first to surface expression errors early.
- After bd upgrades, re-validate formulas using expand/map in CI to catch stricter validation.
When it happens
Trigger: A formula with compose.expand or compose.map entries where the expansion expression doesn't evaluate, the expanded target formula can't be loaded/parsed, or a map entry references a nonexistent parameter or step.
Common situations: Defining compose.map with a variable the target formula doesn't accept; typo'd formula name in compose.expand; generating permutations from an empty/misused collection expression; upgrading bd and hitting stricter expansion validation than when the formula was written.
Related errors
- applying expansions to %q: %w
- branch: from is required
- branch: steps is required
- branch: join is required
- applying control flow: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/b184abd6f59f86c6.
Report an issue: GitHub.