gastownhall/beads · error

formula %q: %w

Error message

formula %q: %w

What it means

Caller-provided variable values are validated by `formula.ValidateProvidedVars` against enum, pattern, and required-empty constraints; failures are wrapped as `formula %q: <detail>`. This is presence-agnostic — omitted vars are the caller's UX concern — but any var explicitly supplied that violates its declared constraint triggers this error. It applies to all shared-path callers (pour, wisp, mol bond/seed); `bd cook --mode=runtime` validates separately.

Source

Thrown at cmd/bd/cook.go:729

	// Resolve inheritance
	resolved, err := parser.Resolve(f)
	if err != nil {
		return nil, fmt.Errorf("resolving formula %q: %w", formulaName, err)
	}

	// 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 {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Read the constraint detail in the wrapped message and supply a value that satisfies the declared enum/pattern
  2. Inspect the variable declaration in the formula file to see the allowed values
  3. Update the formula's enum/pattern if the constraint is outdated for your use case
  4. Stop passing the variable if it is declared required-empty

Example fix

// before
bd mol pour deploy --var env=productions
// after (enum: [dev, staging, prod])
bd mol pour deploy --var env=prod
Defensive patterns

Strategy: validation

Validate before calling

if err := formula.ValidateProvidedVars(resolved, providedVars); err != nil {
    return fmt.Errorf("invalid var values: %w", err)
}

Try / catch

if err != nil {
    var verr *formula.VarConstraintError
    if errors.As(err, &verr) {
        // show allowed enum/pattern for verr.VarName to the user
    }
    return err
}

Prevention

When it happens

Trigger: Passing `--var name=value` where value violates the variable's declaration: value not in the declared enum, not matching the declared regex pattern, or supplied for a variable declared `required-empty`.

Common situations: Environment value drifting from the declared enum after a formula update (e.g. new region list); free-text values pasted where a pattern-constrained ID is expected; supplying values for vars intentionally marked required-empty; shell expansion injecting unexpected values.

Related errors


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