{"record":{"id":"08f9a6ff6596c4ec","repo":"gastownhall/beads","slug":"inline-expand-on-step-q-q-is-not-an-expansion-f","errorCode":null,"errorMessage":"inline expand on step %q: %q is not an expansion formula (type=%s)","messagePattern":"inline expand on step %q: %q is not an expansion formula \\(type=(.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/formula/expand.go","lineNumber":476,"sourceCode":"// depth tracks recursion to prevent infinite expansion loops.\nfunc applyInlineExpansionsRecursive(steps []*Step, parser *Parser, depth int) ([]*Step, error) {\n\tif depth > DefaultMaxExpansionDepth {\n\t\treturn nil, fmt.Errorf(\"inline expansion depth limit exceeded: max %d levels\", DefaultMaxExpansionDepth)\n\t}\n\n\tvar result []*Step\n\n\tfor _, step := range steps {\n\t\t// Check if this step has an inline expansion\n\t\tif step.Expand != \"\" {\n\t\t\t// Load the expansion formula\n\t\t\texpFormula, err := parser.LoadByName(step.Expand)\n\t\t\tif err != nil {\n\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)","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/formula/expand.go#L458-L494","documentation":"Thrown when a step's Expand field resolves to a formula that loaded fine but whose `type` is not \"expansion\". Inline Expand references must point at expansion-type formulas; workflow or other formula types cannot be used as templates. This guards against accidentally expanding a step with a full workflow definition.","triggerScenarios":"ApplyInlineExpansions processes a step whose Expand points to a formula file whose top-level `type` is workflow (the default when type is omitted) or any non-expansion value.","commonSituations":"Author forgets `type = \"expansion\"` in the referenced .formula.toml (type defaults to workflow); pointing Expand at a regular workflow formula by mistake; a formula's type was changed/renamed in a schema update.","solutions":["Add `type = \"expansion\"` to the formula referenced by Expand (and ensure it defines a [[template]] section).","Or change the step's Expand to point at the correct expansion-type formula.","Check the type shown in the error message to see what the formula actually is and correct either side accordingly."],"exampleFix":"// before (scaffolding.formula.toml)\nformula = \"scaffolding\"\n// after\nformula = \"scaffolding\"\ntype = \"expansion\"","handlingStrategy":"validation","validationCode":"for _, s := range steps {\n\tif s.Expand == \"\" {\n\t\tcontinue\n\t}\n\tf, err := parser.LoadByName(s.Expand)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif f.Type != formula.TypeExpansion {\n\t\treturn fmt.Errorf(\"step %q: %q has type %q, want expansion\", s.ID, s.Expand, f.Type)\n\t}\n}","typeGuard":"func isExpansionFormula(f *formula.Formula) bool {\n\treturn f != nil && f.Type == formula.TypeExpansion\n}","tryCatchPattern":null,"preventionTips":["Always declare `type = \"expansion\"` in formulas intended as Expand targets.","Never point Expand at a workflow formula; keep expansion and workflow files separate and clearly named.","Lint formulas in CI: every Expand target must be type expansion."],"tags":["go","formula","config","inline-expansion"],"backgroundTag":"wrong-formula-type","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}