{"record":{"id":"40f7e1506dc4e25d","repo":"gastownhall/beads","slug":"inline-expand-on-step-q-w","errorCode":null,"errorMessage":"inline expand on step %q: %w","messagePattern":"inline expand on step %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/formula/expand.go","lineNumber":490,"sourceCode":"\t\t\t\treturn nil, fmt.Errorf(\"inline expand on step %q: loading %q: %w\", step.ID, step.Expand, err)\n\t\t\t}\n\n\t\t\tif expFormula.Type != TypeExpansion {\n\t\t\t\treturn nil, fmt.Errorf(\"inline expand on step %q: %q is not an expansion formula (type=%s)\",\n\t\t\t\t\tstep.ID, step.Expand, expFormula.Type)\n\t\t\t}\n\n\t\t\tif len(expFormula.Template) == 0 {\n\t\t\t\treturn nil, fmt.Errorf(\"inline expand on step %q: %q has no template steps\", step.ID, step.Expand)\n\t\t\t}\n\n\t\t\t// Merge formula default vars with step's ExpandVars overrides\n\t\t\tvars := mergeVars(expFormula, step.ExpandVars)\n\n\t\t\t// Expand the step using the template (reuse existing expandStep)\n\t\t\texpandedSteps, err := expandStep(step, expFormula.Template, 0, vars)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"inline expand on step %q: %w\", step.ID, err)\n\t\t\t}\n\n\t\t\t// Propagate the original step's dependencies to root steps of the expansion\n\t\t\tpropagateTargetDeps(step, expandedSteps)\n\n\t\t\t// Recursively process expanded steps for nested inline expansions\n\t\t\tprocessedSteps, err := applyInlineExpansionsRecursive(expandedSteps, parser, depth+1)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\n\t\t\tresult = append(result, processedSteps...)\n\t\t} else {\n\t\t\t// No inline expansion - keep the step, but process children recursively\n\t\t\tclone := cloneStep(step)\n\n\t\t\tif len(step.Children) > 0 {\n\t\t\t\tprocessedChildren, err := applyInlineExpansionsRecursive(step.Children, parser, depth)","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/formula/expand.go#L472-L508","documentation":"Wrapper error thrown when expandStep fails while instantiating a step's inline expansion template with merged variables. expandStep performs placeholder substitution ({target.title}, variable refs, repeat logic); any failure there (missing required variable, bad placeholder, invalid repeat spec) is re-wrapped with the offending step ID. The root cause is preserved via %w.","triggerScenarios":"ApplyInlineExpansions calls expandStep(step, expFormula.Template, 0, vars) and the template references variables not provided by the formula defaults nor the step's ExpandVars, or contains malformed placeholders/repeat directives.","commonSituations":"Step omits an ExpandVars entry the template requires; placeholder name typo in the template; template uses iteration variables outside a repeat context; formula defaults removed in a newer formula version.","solutions":["Read the wrapped inner error to identify the failing placeholder or variable.","Add the missing key to the step's ExpandVars or set it as a default var in the expansion formula.","Fix malformed placeholder syntax in the template (e.g. {target.title} vs a typo like {traget.title}).","Validate the formula/template locally by running it through bd before wiring it into a larger workflow."],"exampleFix":"// before\n[[step]]\nid = \"scaffold\"\nexpand = \"scaffolding\"\n# template needs {project.name} but no vars given\n// after\n[[step]]\nid = \"scaffold\"\nexpand = \"scaffolding\"\n[step.expandvars]\nproject_name = \"my-app\"","handlingStrategy":"try-catch","validationCode":"// pre-check that template vars are satisfiable: defaults + ExpandVars cover placeholders used\nvars := map[string]string{}\nfor k, v := range expFormula.Vars {\n\tvars[k] = v\n}\nfor k, v := range step.ExpandVars {\n\tvars[k] = v\n}\nfor _, t := range expFormula.Template {\n\tfor _, ph := range placeholderNames(t) { // scan {var.x} tokens\n\t\tif _, ok := vars[ph]; !ok {\n\t\t\treturn fmt.Errorf(\"step %q: template needs var %q\", step.ID, ph)\n\t\t}\n\t}\n}","typeGuard":null,"tryCatchPattern":"expanded, err := formula.ApplyInlineExpansions(steps, parser)\nif err != nil {\n\tif strings.Contains(err.Error(), \"inline expand on step\") {\n\t\treturn fmt.Errorf(\"expanding %s: %w\", stepID, err) // surface inner cause to user\n\t}\n\treturn err\n}","preventionTips":["Provide ExpandVars for every variable the template references, or set defaults in the formula.","Keep placeholder names simple and consistent ({target.title}, {var.name}) and review template edits.","Run formulas through a dry-run/expansion test before wiring them into workflows."],"tags":["go","formula","template","variable-substitution"],"backgroundTag":"template-variable-missing","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}