{"record":{"id":"dac7c4e71f0710a4","repo":"gastownhall/beads","slug":"resolving-formula-w","errorCode":null,"errorMessage":"resolving formula: %w","messagePattern":"resolving formula: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/cook.go","lineNumber":170,"sourceCode":"// It first tries to load by name from the formula registry (.beads/formulas/),\n// and falls back to parsing as a file path if that fails.\nfunc loadAndResolveFormula(formulaPath string, searchPaths []string) (*formula.Formula, error) {\n\tparser := formula.NewParser(searchPaths...)\n\n\t// Try to load by name first (from .beads/formulas/ registry)\n\tf, err := parser.LoadByName(formulaPath)\n\tif err != nil {\n\t\t// Fall back to parsing as a file path\n\t\tf, err = parser.ParseFile(formulaPath)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"parsing formula: %w\", err)\n\t\t}\n\t}\n\n\t// Resolve inheritance\n\tresolved, err := parser.Resolve(f)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"resolving formula: %w\", err)\n\t}\n\n\t// Apply control flow operators - loops, branches, gates\n\tcontrolFlowSteps, err := formula.ApplyControlFlow(resolved.Steps, resolved.Compose)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"applying control flow: %w\", err)\n\t}\n\tresolved.Steps = controlFlowSteps\n\n\t// Apply advice transformations\n\tif len(resolved.Advice) > 0 {\n\t\tresolved.Steps = formula.ApplyAdvice(resolved.Steps, resolved.Advice)\n\t}\n\n\t// Apply inline step expansions\n\tinlineExpandedSteps, err := formula.ApplyInlineExpansions(resolved.Steps, parser)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"applying inline expansions: %w\", err)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/cook.go#L152-L188","documentation":"cmd/bd/cook.go:170 wraps errors from parser.Resolve(f), which resolves the formula's inheritance chain (extends/parents). The formula itself parsed fine, but walking its parent references failed — typically a missing parent formula, a cycle (A extends B extends A), or depth/recursion problems. %w preserves the underlying reason so callers can distinguish missing-parent from cycle cases.","triggerScenarios":"parser.Resolve is called on a successfully parsed Formula whose inheritance metadata references a parent name not present in the registry, or whose parents form a cycle, or whose inheritance tree exceeds allowed depth.","commonSituations":"A formula was copied to another repo without its base formula; a refactor renamed a parent formula but children still extend the old name; someone hand-edited `extends` and created a self-reference or loop.","solutions":["Check the formula's extends/parent references and ensure every named parent exists in .beads/formulas/.","Trace the inheritance chain for cycles (A→B→A or extends: self) and break the loop.","Re-read the wrapped error: 'not found' → add/commit the parent formula; 'cycle' → fix the extends graph.","If the base formula was renamed, update all children's extends fields to the new name."],"exampleFix":"// before (formula frontmatter)\nextends: base-workflow   # renamed to core-workflow\n// after\nextends: core-workflow","handlingStrategy":"validation","validationCode":"func inheritanceChainOK(f *formula.Formula, lookup func(string) (*formula.Formula, error)) error {\n\tseen := map[string]bool{}\n\tvar walk func(cur *formula.Formula) error\n\twalk = func(cur *formula.Formula) error {\n\t\tfor _, p := range cur.Extends {\n\t\t\tif seen[p] {\n\t\t\t\treturn fmt.Errorf(\"inheritance cycle at %q\", p)\n\t\t\t}\n\t\t\tseen[p] = true\n\t\t\tparent, err := lookup(p)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"parent formula %q missing: %w\", p, err)\n\t\t\t}\n\t\t\tif err := walk(parent); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t\treturn nil\n\t}\n\treturn walk(f)\n}","typeGuard":"func hasKnownParents(f *formula.Formula, registry map[string]*formula.Formula) bool {\n\tfor _, p := range f.Extends {\n\t\tif _, ok := registry[p]; !ok {\n\t\t\treturn false\n\t\t}\n\t}\n\treturn true\n}","tryCatchPattern":"resolved, err := parser.Resolve(f)\nif err != nil {\n\tif strings.Contains(err.Error(), \"cycle\") {\n\t\treturn fmt.Errorf(\"formula inheritance cycle: fix extends chain in %s\", f.Name)\n\t}\n\treturn fmt.Errorf(\"missing parent formula: %w\", err)\n}","preventionTips":["When renaming a parent formula, grep all formulas' extends fields and update them in the same commit.","Never let a formula extend itself, directly or transitively; document the inheritance tree.","Copy base formulas together with their children when moving formulas between repos.","Add a CI check that resolves every formula in .beads/formulas/ with parser.Resolve."],"tags":["formula","inheritance","resolution","cycle"],"backgroundTag":"formula-inheritance-resolution-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}