{"record":{"id":"97acc78c12df3c37","repo":"gastownhall/beads","slug":"applying-control-flow-to-q-w","errorCode":null,"errorMessage":"applying control flow to %q: %w","messagePattern":"applying control flow to %q: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/cook.go","lineNumber":736,"sourceCode":"\t// Validate any caller-provided variable values against enum/pattern/\n\t// required-empty constraints. This is deliberately presence-agnostic:\n\t// a var missing entirely is left to the caller's own UX (e.g. bd mol\n\t// pour/wisp's missing-var hint), but a var explicitly provided with a\n\t// value that violates its constraints must error here so it reaches\n\t// every caller of this shared path (pour, wisp, mol bond, mol seed) —\n\t// runCook does not go through this helper; it validates separately via\n\t// its own formula.ValidateVars call under --mode=runtime. Previously\n\t// only that `bd cook --mode=runtime` path enforced these (mybd-u2r6).\n\tif conditionVars != nil {\n\t\tif err := formula.ValidateProvidedVars(resolved, conditionVars); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"formula %q: %w\", formulaName, err)\n\t\t}\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 to %q: %w\", formulaName, 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 to %q: %w\", formulaName, 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":718,"sourceCodeEnd":754,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/cook.go#L718-L754","documentation":"After variable validation, the helper applies control-flow operators (loops, branches, gates) via `formula.ApplyControlFlow`; failures are wrapped as `applying control flow to %q`. The formula's structural operators are malformed — e.g. a loop with no range, a branch with no condition, a gate referencing an unknown variable — so the step list cannot be expanded.","triggerScenarios":"Any shared-path command (pour, wisp, mol bond/seed, verify) on a formula whose steps use control-flow operators that `ApplyControlFlow` rejects: missing/invalid loop ranges, branch conditions that don't evaluate, gates over undeclared variables, malformed operator syntax in step definitions.","commonSituations":"Hand-authoring loops/branches for the first time and getting operator syntax wrong; formula edited to gate on a variable that was removed from the declarations; upgrading beads where operator validation tightened; copy-pasted control-flow blocks with placeholder values.","solutions":["Read the wrapped detail to find which step/operator failed and fix its definition in the formula file","Verify loop ranges, branch conditions, and gate variables all reference declared formula variables","Simplify by temporarily replacing the control-flow block with plain steps, confirm the formula cooks, then reintroduce operators incrementally","Run `bd formula validate <name>` after edits to catch operator errors before runtime"],"exampleFix":"// before (step)\n- id: deploy\n  for_each: regions   # regions not declared\n// after\nvariables:\n  - name: regions\n    type: list\n- id: deploy\n  for_each: regions","handlingStrategy":"validation","validationCode":"// gate/loop variables must be declared\nfor _, ref := range collectControlFlowVarRefs(steps) {\n    if !declaredVars[ref] {\n        return fmt.Errorf(\"control-flow references undeclared var %q\", ref)\n    }\n}","typeGuard":null,"tryCatchPattern":"if err != nil {\n    return fmt.Errorf(\"applying control flow to %q: %w\", name, err)\n    // fix the operator in the formula file; do not retry blindly\n}","preventionTips":["Declare every variable referenced by for_each/branch/gate operators","Introduce control-flow blocks incrementally and run bd formula validate after each","When removing a variable, grep the formula for operator references to it first"],"tags":["formula","control-flow","validation"],"backgroundTag":"formula-control-flow-apply-failed","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}