gastownhall/beads · error
inline expansion depth limit exceeded: max %d levels
Error message
inline expansion depth limit exceeded: max %d levels
What it means
This error is thrown by applyInlineExpansionsRecursive in internal/formula/expand.go when processing inline step expansions (steps with an Expand field) recurses deeper than DefaultMaxExpansionDepth levels. The library imposes a hard recursion cap so a formula whose expansion references itself (directly or transitively) cannot loop forever. It typically indicates a cycle in the Expand references among expansion formulas.
Source
Thrown at internal/formula/expand.go:461
//
// This differs from compose.Expand in that the expansion is declared inline on the
// step itself rather than in a central compose section.
//
// Returns a new steps slice with inline expansions applied.
// The original steps slice is not modified.
func ApplyInlineExpansions(steps []*Step, parser *Parser) ([]*Step, error) {
if parser == nil {
return steps, nil
}
return applyInlineExpansionsRecursive(steps, parser, 0)
}
// applyInlineExpansionsRecursive handles inline expansions for a slice of steps.
// 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)
}
View on GitHub (pinned to 71377f2769)
Solutions
- Inspect the Expand fields along the chain and break the cycle (remove the self/back reference).
- Flatten overly deep nesting by inlining some template steps directly instead of chaining Expand references.
- If legitimately deep nesting is required, raise DefaultMaxExpansionDepth in the source or refactor into a compose-style expansion.
- Log/print the Expand chain per step to identify which formula repeats.
Example fix
// before (mutual cycle) // a.formula.toml: [[template]] expand = "b" // b.formula.toml: [[template]] expand = "a" // after // b.formula.toml: [[template]] id = "real-step" (no back-reference to a)
Defensive patterns
Strategy: validation
Validate before calling
func assertAcyclicExpand(parser *formula.Parser, names []string) error {
seen := map[string]bool{}
var walk func(name string) error
walk = func(name string) error {
if seen[name] {
return fmt.Errorf("inline expand cycle at %s", name)
}
seen[name] = true
defer delete(seen, name)
f, err := parser.LoadByName(name)
if err != nil {
return err
}
for _, s := range f.Template {
if s.Expand != "" {
if err := walk(s.Expand); err != nil {
return err
}
}
}
return nil
}
for _, n := range names {
if err := walk(n); err != nil {
return err
}
}
return nil
} Prevention
- Never let an expansion template reference a formula that (transitively) references it back.
- Keep expansion nesting shallow; inline template steps instead of chaining Expand beyond a few levels.
- Add a CI test that walks all repo formulas' Expand chains to detect cycles early.
When it happens
Trigger: Calling ApplyInlineExpansions on a steps slice where inline Expand references chain through expansion templates that themselves contain Expand steps, more than DefaultMaxExpansionDepth levels deep — typically because formula A's template expands to formula B, and B back to A.
Common situations: Two .formula.toml files accidentally expand each other; copying an Expand line into a template that references its own formula; building deeply nested modular expansions that exceed the fixed depth budget.
Related errors
- applying inline expansions: %w
- inline expand on step %q: loading %q: %w
- inline expand on step %q: %q is not an expansion formula (ty
- applying inline expansions to %q: %w
- formula %q not accessible: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/5c25d86030dc8f10.
Report an issue: GitHub.