gastownhall/beads · error
inline expand on step %q: %q is not an expansion formula (ty
Error message
inline expand on step %q: %q is not an expansion formula (type=%s)
What it means
Thrown when a step's Expand field resolves to a formula that loaded fine but whose `type` is not "expansion". Inline Expand references must point at expansion-type formulas; workflow or other formula types cannot be used as templates. This guards against accidentally expanding a step with a full workflow definition.
Source
Thrown at internal/formula/expand.go:476
// depth tracks recursion to prevent infinite expansion loops.
func applyInlineExpansionsRecursive(steps []*Step, parser *Parser, depth int) ([]*Step, error) {
if depth > DefaultMaxExpansionDepth {
return nil, fmt.Errorf("inline expansion depth limit exceeded: max %d levels", DefaultMaxExpansionDepth)
}
var result []*Step
for _, step := range steps {
// Check if this step has an inline expansion
if step.Expand != "" {
// Load the expansion formula
expFormula, err := parser.LoadByName(step.Expand)
if err != nil {
return nil, fmt.Errorf("inline expand on step %q: loading %q: %w", step.ID, step.Expand, err)
}
if expFormula.Type != TypeExpansion {
return nil, fmt.Errorf("inline expand on step %q: %q is not an expansion formula (type=%s)",
step.ID, step.Expand, expFormula.Type)
}
if len(expFormula.Template) == 0 {
return nil, fmt.Errorf("inline expand on step %q: %q has no template steps", step.ID, step.Expand)
}
// Merge formula default vars with step's ExpandVars overrides
vars := mergeVars(expFormula, step.ExpandVars)
// Expand the step using the template (reuse existing expandStep)
expandedSteps, err := expandStep(step, expFormula.Template, 0, vars)
if err != nil {
return nil, fmt.Errorf("inline expand on step %q: %w", step.ID, err)
}
// Propagate the original step's dependencies to root steps of the expansion
propagateTargetDeps(step, expandedSteps)View on GitHub (pinned to 71377f2769)
Solutions
- Add `type = "expansion"` to the formula referenced by Expand (and ensure it defines a [[template]] section).
- Or change the step's Expand to point at the correct expansion-type formula.
- Check the type shown in the error message to see what the formula actually is and correct either side accordingly.
Example fix
// before (scaffolding.formula.toml) formula = "scaffolding" // after formula = "scaffolding" type = "expansion"
Defensive patterns
Strategy: validation
Validate before calling
for _, s := range steps {
if s.Expand == "" {
continue
}
f, err := parser.LoadByName(s.Expand)
if err != nil {
return err
}
if f.Type != formula.TypeExpansion {
return fmt.Errorf("step %q: %q has type %q, want expansion", s.ID, s.Expand, f.Type)
}
} Type guard
func isExpansionFormula(f *formula.Formula) bool {
return f != nil && f.Type == formula.TypeExpansion
} Prevention
- Always declare `type = "expansion"` in formulas intended as Expand targets.
- Never point Expand at a workflow formula; keep expansion and workflow files separate and clearly named.
- Lint formulas in CI: every Expand target must be type expansion.
When it happens
Trigger: ApplyInlineExpansions processes a step whose Expand points to a formula file whose top-level `type` is workflow (the default when type is omitted) or any non-expansion value.
Common situations: Author forgets `type = "expansion"` in the referenced .formula.toml (type defaults to workflow); pointing Expand at a regular workflow formula by mistake; a formula's type was changed/renamed in a schema update.
Related errors
- inline expansion depth limit exceeded: max %d levels
- inline expand on step %q: loading %q: %w
- inline expand on step %q: %q has no template steps
- server: NewDoltServer: doltBinExec is required
- server: NewDoltServer: rootDir is required
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/08f9a6ff6596c4ec.
Report an issue: GitHub.