{"record":{"id":"9ac4b870d465a6a1","repo":"gastownhall/beads","slug":"applying-control-flow-w","errorCode":null,"errorMessage":"applying control flow: %w","messagePattern":"applying control flow: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/cook.go","lineNumber":176,"sourceCode":"\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)\n\t}\n\tresolved.Steps = inlineExpandedSteps\n\n\t// Apply expansion operators\n\tif resolved.Compose != nil && (len(resolved.Compose.Expand) > 0 || len(resolved.Compose.Map) > 0) {\n\t\texpandedSteps, err := formula.ApplyExpansions(resolved.Steps, resolved.Compose, parser)","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/cook.go#L158-L194","documentation":"cmd/bd/cook.go:176 wraps errors from formula.ApplyControlFlow(resolved.Steps, resolved.Compose), which evaluates control-flow operators (loops, branches, gates) declared in the formula into a flat step list. The formula resolved cleanly, but a control-flow construct is invalid: e.g. a loop with no iterable/bad range expression, a branch with missing condition or missing target steps, or a gate referencing an undefined step.","triggerScenarios":"A formula step uses control-flow syntax (foreach/loop, branch/if, gate) and ApplyControlFlow cannot evaluate it: empty or malformed loop collection expression, branch condition that doesn't parse, branch/gate target step id that doesn't exist in the step list.","commonSituations":"Hand-written loop expressions with wrong variable syntax; a branch referencing a step renamed or removed during editing; a gate condition using a variable not provided to the run; copy-pasting control-flow blocks between formulas without adjusting step ids.","solutions":["Read the wrapped error to identify the offending operator (loop/branch/gate) and step id, then fix that construct in the formula file.","Verify every branch/gate target references an existing step id in the same formula.","Validate loop expressions: correct variable name, non-empty collection, correct syntax for the range/foreach form.","Remove or comment out the control-flow block and re-run to isolate which construct is malformed."],"exampleFix":"// before (formula step)\nbranch: on-fail -> step: \"verify-fix\"   # step id renamed\n// after\nbranch: on-fail -> step: \"verify\"       # matches existing step id","handlingStrategy":"validation","validationCode":"func controlFlowTargetsExist(steps []*formula.Step) error {\n\tids := map[string]bool{}\n\tfor _, s := range steps {\n\t\tids[s.ID] = true\n\t}\n\tfor _, s := range steps {\n\t\tfor _, target := range s.ControlFlowTargets() { // branch/gate step references\n\t\t\tif !ids[target] {\n\t\t\t\treturn fmt.Errorf(\"step %q references unknown step %q\", s.ID, target)\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}","typeGuard":"func stepExists(steps []*formula.Step, id string) bool {\n\tfor _, s := range steps {\n\t\tif s.ID == id {\n\t\t\treturn true\n\t\t}\n\t}\n\treturn false\n}","tryCatchPattern":"steps, err := formula.ApplyControlFlow(resolved.Steps, resolved.Compose)\nif err != nil {\n\treturn fmt.Errorf(\"bad loop/branch/gate in formula %q: %w\", formulaName, err)\n}","preventionTips":["After renaming or deleting a step, update every branch/gate that targets its id.","Keep loop collection expressions simple and test them with a two-item list before generalizing.","Validate formulas in CI by running ApplyControlFlow on each registry entry.","Provide all variables a gate condition reads at cook time; avoid optional gate vars."],"tags":["formula","control-flow","loops","validation"],"backgroundTag":"formula-control-flow-invalid","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}