gastownhall/beads · error

map %q -> %q: %w

Error message

map %q -> %q: %w

What it means

Wraps an expandStep failure while expanding one matched step in a map rule. Selects the pattern (rule.Select) and the specific matched step ID (targetStep.ID) to identify which match failed; the inner error is usually a depth-limit or substitution error.

Source

Thrown at internal/formula/expand.go:137

		// Merge formula default vars with rule overrides
		vars := mergeVars(expFormula, rule.Vars)

		// Find all matching steps (including nested children)
		// Rebuild stepMap to capture any changes from previous expansions
		stepMap = buildStepMap(result)
		var toExpand []*Step
		for id, step := range stepMap {
			if MatchGlob(rule.Select, id) && !expanded[id] {
				toExpand = append(toExpand, step)
			}
		}

		// Expand each matching step
		for _, targetStep := range toExpand {
			expandedSteps, err := expandStep(targetStep, expFormula.Template, 0, vars)
			if err != nil {
				return nil, fmt.Errorf("map %q -> %q: %w", rule.Select, targetStep.ID, err)
			}

			// Propagate target step's dependencies to root steps of the expansion
			propagateTargetDeps(targetStep, expandedSteps)

			result = replaceStep(result, targetStep.ID, expandedSteps)
			expanded[targetStep.ID] = true

			// Update dependencies: any step that depended on the target should now
			// depend on the last step of the expansion
			if len(expandedSteps) > 0 {
				lastStepID := expandedSteps[len(expandedSteps)-1].ID
				result = UpdateDependenciesForExpansion(result, targetStep.ID, lastStepID)
			}

			// Rebuild stepMap from result so subsequent iterations see resolved deps
			stepMap = buildStepMap(result)
		}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Inspect the wrapped inner error and the named step
  2. Lower recursion or add a guard condition to the select pattern to avoid re-matching expanded steps
  3. Supply missing template variables via formula defaults or rule.Vars

Example fix

# before
map:
  - select: "*"        # matches expanded children too -> runaway recursion
    with: expand-all
# after
map:
  - select: "gen-*"    # narrow pattern
    with: expand-all
Defensive patterns

Strategy: try-catch

Try / catch

expanded, err := formula.ApplyExpansions(steps, compose)
if err != nil {
    if strings.Contains(err.Error(), "depth limit") {
        return fmt.Errorf("map expansion recursed too deep: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: ApplyExpansions iterates steps matched by a map rule's select pattern and expandStep fails for one of them (depth > 5, template/var problem).

Common situations: A select pattern matches nested steps so expansion cascades deeper than expected; template placeholders referencing variables not defined; recursive templates where expansion output re-matches the select pattern.

Related errors


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