gastownhall/beads · error

expand: loading

Error message

expand: loading %q: %w

What it means

ApplyExpansions wraps failures from parser.LoadByName when loading the expansion formula named by a compose.Expand rule's With field. The With value must resolve to a loaded expansion-type formula whose template replaces the target step. This error means the named formula could not be found or parsed, and the load failure is preserved via %w.

Solutions

  1. Read the wrapped error to see whether the formula was not found or failed to parse
  2. Confirm the With name matches an existing expansion formula (Type: expansion) visible to the parser's search paths
  3. Validate/parse the referenced formula file directly to surface any YAML or schema errors
  4. Update stale With references after renaming expansion formulas

Example fix

// before
expand:
  - target: review
    with: revew-checklist
// after
expand:
  - target: review
    with: review-checklist
Defensive patterns

Strategy: validation

Validate before calling

for _, r := range compose.Expand {
	f, err := parser.LoadByName(r.With)
	if err != nil {
		return fmt.Errorf("expansion %q unavailable: %w", r.With, err)
	}
	if f.Type != TypeExpansion {
		return fmt.Errorf("%q is type %s, want expansion", r.With, f.Type)
	}
}

Try / catch

result, err := ApplyExpansions(steps, compose, parser)
if err != nil {
	var loadErr error
	if _, scanErr := fmt.Sscanf(err.Error(), "expand: loading %q", new(any)); scanErr == nil {
		loadErr = errors.Unwrap(err)
	}
	return fmt.Errorf("expansion formula load failed: %w", errors.Join(err, loadErr))
}

Prevention

When it happens

Trigger: Calling ApplyExpansions(steps, compose, parser) where compose.Expand[].With names a formula that is not registered with the parser, does not exist on disk/in the registry, or fails to parse.

Common situations: Referencing an expansion formula that was never defined or has a different name; formula file not in the parser's search path; YAML syntax error inside the referenced expansion formula; renaming an expansion formula without updating expand/map rules that use it.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/dd5567e808678032. Report an issue: GitHub.

Appendix: source

Thrown at internal/formula/expand.go:64

	// Track which steps have been expanded (to avoid double expansion)
	expanded := make(map[string]bool)

	// Apply expand rules first (specific targets)
	result := steps
	for _, rule := range compose.Expand {
		targetStep, ok := stepMap[rule.Target]
		if !ok {
			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)
		}

View on GitHub (pinned to 71377f2769)