{"record":{"id":"549c7aa6945a0717","repo":"gastownhall/beads","slug":"expand-q-w","errorCode":null,"errorMessage":"expand %q: %w","messagePattern":"expand %q: %w","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/formula/expand.go","lineNumber":81,"sourceCode":"\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"expand: loading %q: %w\", rule.With, err)\n\t\t}\n\n\t\tif expFormula.Type != TypeExpansion {\n\t\t\treturn nil, fmt.Errorf(\"expand: %q is not an expansion formula (type=%s)\", rule.With, expFormula.Type)\n\t\t}\n\n\t\tif len(expFormula.Template) == 0 {\n\t\t\treturn nil, fmt.Errorf(\"expand: %q has no template steps\", rule.With)\n\t\t}\n\n\t\t// Merge formula default vars with rule overrides\n\t\tvars := mergeVars(expFormula, rule.Vars)\n\n\t\t// Expand the target step (start at depth 0)\n\t\texpandedSteps, err := expandStep(targetStep, expFormula.Template, 0, vars)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"expand %q: %w\", rule.Target, err)\n\t\t}\n\n\t\t// Propagate target step's dependencies to root steps of the expansion.\n\t\t// Root steps are those whose needs/dependsOn only reference IDs within\n\t\t// the expansion (or are empty) — they are the entry points.\n\t\tpropagateTargetDeps(targetStep, expandedSteps)\n\n\t\t// Replace the target step with expanded steps\n\t\tresult = replaceStep(result, rule.Target, expandedSteps)\n\t\texpanded[rule.Target] = true\n\n\t\t// Update dependencies: any step that depended on the target should now\n\t\t// depend on the last step of the expansion\n\t\tif len(expandedSteps) > 0 {\n\t\t\tlastStepID := expandedSteps[len(expandedSteps)-1].ID\n\t\t\tresult = UpdateDependenciesForExpansion(result, rule.Target, lastStepID)\n\t\t}\n","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/formula/expand.go#L63-L99","documentation":"Wraps an error returned by expandStep while expanding the target step of an `expand` rule. The inner error is most often the depth-limit error or a variable/template substitution failure; this wrapper adds the target step ID for context.","triggerScenarios":"ApplyExpansions -> expandStep fails while processing a compose `expand` rule targeting step `rule.Target` (e.g. expansion depth exceeded DefaultMaxExpansionDepth=5, or template placeholder issues).","commonSituations":"Deeply recursive expansion templates; template referencing undefined variables causing substitution errors; chained expansions expanding each other beyond the depth limit.","solutions":["Read the wrapped inner error for the root cause","Reduce recursion in the expansion template or refactor into explicit steps","Verify all {var} placeholders in the template are provided via formula defaults or rule.Vars"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"expanded, err := formula.ApplyExpansions(steps, compose)\nif err != nil {\n    var de *formula.DepthError // or match \"expand %q:\"\n    if strings.Contains(err.Error(), \"depth limit\") {\n        return fmt.Errorf(\"expansion too deep for target %s: %w\", rule.Target, err)\n    }\n    return err\n}","preventionTips":["Keep expansion templates non-recursive","Supply all template variables via formula defaults or rule.Vars","Test expansion-heavy composes with a depth-sensitive unit test"],"tags":["expansion","recursion","formula"],"backgroundTag":"expansion-depth-limit-exceeded","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}