gastownhall/beads · error
expand: %q has no template steps
Error message
expand: %q has no template steps
What it means
The `with:` formula in an expand rule is a valid expansion formula, but its template has zero steps. An expansion with no template steps cannot produce any steps, so ApplyExpansions rejects it rather than silently deleting the target step.
Source
Thrown at internal/formula/expand.go:72
return nil, fmt.Errorf("expand: target step %q not found", rule.Target)
}
if expanded[rule.Target] {
continue // Already expanded
}
// Load the expansion formula
expFormula, err := parser.LoadByName(rule.With)
if err != nil {
return nil, fmt.Errorf("expand: loading %q: %w", rule.With, err)
}
if expFormula.Type != TypeExpansion {
return nil, fmt.Errorf("expand: %q is not an expansion formula (type=%s)", rule.With, expFormula.Type)
}
if len(expFormula.Template) == 0 {
return nil, fmt.Errorf("expand: %q has no template steps", rule.With)
}
// Merge formula default vars with rule overrides
vars := mergeVars(expFormula, rule.Vars)
// Expand the target step (start at depth 0)
expandedSteps, err := expandStep(targetStep, expFormula.Template, 0, vars)
if err != nil {
return nil, fmt.Errorf("expand %q: %w", rule.Target, err)
}
// Propagate target step's dependencies to root steps of the expansion.
// Root steps are those whose needs/dependsOn only reference IDs within
// the expansion (or are empty) — they are the entry points.
propagateTargetDeps(targetStep, expandedSteps)
// Replace the target step with expanded steps
result = replaceStep(result, rule.Target, expandedSteps)View on GitHub (pinned to 71377f2769)
Solutions
- Add template steps to the referenced expansion formula
- Restore accidentally removed/commented template steps
- Fix the misspelled template key so the steps parse into the formula
Example fix
# before
name: matrix-expand
type: expansion
# steps missing
# after
name: matrix-expand
type: expansion
steps:
- id: "item-${item}"
title: "Item ${item}" Defensive patterns
Strategy: validation
Validate before calling
f, _ := parser.LoadByName(rule.With)
if f.Type == formula.TypeExpansion && len(f.Template) == 0 {
return fmt.Errorf("expansion formula %q has no template steps", rule.With)
} Type guard
func hasTemplate(f *formula.Formula) bool { return f != nil && f.Type == formula.TypeExpansion && len(f.Template) > 0 } Try / catch
expanded, err := formula.ApplyExpansions(steps, compose)
if err != nil && strings.Contains(err.Error(), "has no template steps") {
return fmt.Errorf("expansion formula %s is empty: %w", rule.With, err)
} Prevention
- Every `type: expansion` formula must define at least one template step — lint for it
- Don't leave steps commented out in committed formulas
- Parse formulas in CI to catch empty templates early
When it happens
Trigger: ApplyExpansions encounters an expand rule whose formula passes the TypeExpansion check but has an empty Template slice (no steps defined in the formula file).
Common situations: Formula file defines type: expansion but no steps/template section; steps were commented out or removed during editing; a template YAML/JSON key was misspelled so it parsed to an empty list.
Related errors
- standalone expansion %q: %w
- applying expansions: %w
- applying expansions to %q: %w
- expand: target step %q not found
- expand: loading %q: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0c197d8daa32d9f8.
Report an issue: GitHub.