{"record":{"id":"32a2607ab50a9941","repo":"gastownhall/beads","slug":"formula-q-not-found-in-search-paths","errorCode":null,"errorMessage":"formula %q not found in search paths","messagePattern":"formula %q not found in search paths","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/formula/parser.go","lineNumber":303,"sourceCode":"// Tries TOML first (.formula.toml), then falls back to JSON (.formula.json).\nfunc (p *Parser) loadFormula(name string) (*Formula, error) {\n\t// Check cache first\n\tif cached, ok := p.cache[name]; ok {\n\t\treturn cached, nil\n\t}\n\n\t// Search for the formula file - try TOML first, then JSON\n\textensions := []string{FormulaExtTOML, FormulaExtJSON}\n\tfor _, dir := range p.searchPaths {\n\t\tfor _, ext := range extensions {\n\t\t\tpath := filepath.Join(dir, name+ext)\n\t\t\tif _, err := os.Stat(path); err == nil {\n\t\t\t\treturn p.ParseFile(path)\n\t\t\t}\n\t\t}\n\t}\n\n\treturn nil, fmt.Errorf(\"formula %q not found in search paths\", name)\n}\n\n// LoadByName loads a formula by name from search paths.\n// This is the public API for loading formulas used by expansion operators.\nfunc (p *Parser) LoadByName(name string) (*Formula, error) {\n\treturn p.loadFormula(name)\n}\n\n// mergeSteps merges child steps into parent steps.\n// Child steps with the same ID as a parent step replace the parent step\n// in-place (preserving position). Child steps with new IDs are appended.\nfunc mergeSteps(parent, child []*Step) []*Step {\n\t// Index parent steps by ID for quick lookup\n\tparentIdx := make(map[string]int, len(parent))\n\tfor i, s := range parent {\n\t\tparentIdx[s.ID] = i\n\t}\n","sourceCodeStart":285,"sourceCodeEnd":321,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/internal/formula/parser.go#L285-L321","documentation":"loadFormula() searched every configured search path for a formula file matching the requested name and found nothing (os.Stat failed for each candidate path). It is the library's canonical 'no such formula' error, exposed publicly through LoadByName for expansion operators.","triggerScenarios":"Parser.LoadByName(\"name\") with no matching formula file in the search paths; Resolve on a formula whose extends entry names a nonexistent parent (then wrapped by 1741); expansion operators resolving a formula reference that does not exist.","commonSituations":"Typos in the formula name; formula file never created; file lives outside the configured search paths; wrong file extension or naming convention so the Stat candidate paths never match; working from a different repo checkout where the formula directory is absent.","solutions":["Verify the formula file exists and its name matches exactly (case-sensitive) what you passed to LoadByName or put in extends.","Add the formula's directory to the parser's search paths when constructing the Parser.","List the search-path directories and the formulas in them to confirm the expected file is present and named per convention."],"exampleFix":"// before\np := NewParser(WithSearchPaths(\"./formulas\"))\nf, err := p.LoadByName(\"deploy\") // file is in ./molecules/deploy.md\n\n// after\np := NewParser(WithSearchPaths(\"./formulas\", \"./molecules\"))\nf, err := p.LoadByName(\"deploy\")","handlingStrategy":"validation","validationCode":"// Verify the formula file exists in a search path before LoadByName.\nfunc formulaExists(name string, searchPaths []string) bool {\n\tfor _, dir := range searchPaths {\n\t\tif _, err := os.Stat(filepath.Join(dir, name+\".md\")); err == nil {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":"f, err := p.LoadByName(name)\nif err != nil {\n\tif strings.Contains(err.Error(), \"not found in search paths\") {\n\t\t// suggest closest matches by listing the search dirs\n\t}\n}","preventionTips":["Configure all formula directories in WithSearchPaths up front.","Match names exactly (case-sensitive) to filenames; avoid ad-hoc renaming.","Provide a 'list formulas' command built on the same search paths so users can see valid names."],"tags":["go","formula","file-not-found","search-path"],"backgroundTag":"formula-not-found","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}