gastownhall/beads · error

applying control flow to %q: %w

Error message

applying control flow to %q: %w

What it means

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.

Source

Thrown at cmd/bd/cook.go:736

	// Validate any caller-provided variable values against enum/pattern/
	// required-empty constraints. This is deliberately presence-agnostic:
	// a var missing entirely is left to the caller's own UX (e.g. bd mol
	// pour/wisp's missing-var hint), but a var explicitly provided with a
	// value that violates its constraints must error here so it reaches
	// every caller of this shared path (pour, wisp, mol bond, mol seed) —
	// runCook does not go through this helper; it validates separately via
	// its own formula.ValidateVars call under --mode=runtime. Previously
	// only that `bd cook --mode=runtime` path enforced these (mybd-u2r6).
	if conditionVars != nil {
		if err := formula.ValidateProvidedVars(resolved, conditionVars); err != nil {
			return nil, fmt.Errorf("formula %q: %w", formulaName, err)
		}
	}

	// Apply control flow operators - loops, branches, gates
	controlFlowSteps, err := formula.ApplyControlFlow(resolved.Steps, resolved.Compose)
	if err != nil {
		return nil, fmt.Errorf("applying control flow to %q: %w", formulaName, err)
	}
	resolved.Steps = controlFlowSteps

	// Apply advice transformations
	if len(resolved.Advice) > 0 {
		resolved.Steps = formula.ApplyAdvice(resolved.Steps, resolved.Advice)
	}

	// Apply inline step expansions
	inlineExpandedSteps, err := formula.ApplyInlineExpansions(resolved.Steps, parser)
	if err != nil {
		return nil, fmt.Errorf("applying inline expansions to %q: %w", formulaName, err)
	}
	resolved.Steps = inlineExpandedSteps

	// Apply expansion operators
	if resolved.Compose != nil && (len(resolved.Compose.Expand) > 0 || len(resolved.Compose.Map) > 0) {
		expandedSteps, err := formula.ApplyExpansions(resolved.Steps, resolved.Compose, parser)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the wrapped detail to find which step/operator failed and fix its definition in the formula file
  2. Verify loop ranges, branch conditions, and gate variables all reference declared formula variables
  3. Simplify by temporarily replacing the control-flow block with plain steps, confirm the formula cooks, then reintroduce operators incrementally
  4. Run `bd formula validate <name>` after edits to catch operator errors before runtime

Example fix

// before (step)
- id: deploy
  for_each: regions   # regions not declared
// after
variables:
  - name: regions
    type: list
- id: deploy
  for_each: regions
Defensive patterns

Strategy: validation

Validate before calling

// gate/loop variables must be declared
for _, ref := range collectControlFlowVarRefs(steps) {
    if !declaredVars[ref] {
        return fmt.Errorf("control-flow references undeclared var %q", ref)
    }
}

Try / catch

if err != nil {
    return fmt.Errorf("applying control flow to %q: %w", name, err)
    // fix the operator in the formula file; do not retry blindly
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/97acc78c12df3c37. Report an issue: GitHub.