gastownhall/beads · error
loop %q: invalid until condition %q: %w
Error message
loop %q: invalid until condition %q: %w
What it means
validateLoopSpec parses the loop's Until condition with ParseCondition and wraps any parse failure. The until condition is a condition expression evaluated each iteration to stop the loop; if its syntax is invalid the loop can never be safely expanded.
Source
Thrown at internal/formula/controlflow.go:96
return fmt.Errorf("loop %q: only one of count, until, or range can be specified", stepID)
}
if loop.Until != "" && loop.Max == 0 {
return fmt.Errorf("loop %q: max is required when until is set", stepID)
}
if loop.Count < 0 {
return fmt.Errorf("loop %q: count must be positive", stepID)
}
if loop.Max < 0 {
return fmt.Errorf("loop %q: max must be positive", stepID)
}
// Validate until condition syntax if present
if loop.Until != "" {
if _, err := ParseCondition(loop.Until); err != nil {
return fmt.Errorf("loop %q: invalid until condition %q: %w", stepID, loop.Until, err)
}
}
// Validate range syntax if present
if loop.Range != "" {
if err := ValidateRange(loop.Range); err != nil {
return fmt.Errorf("loop %q: invalid range %q: %w", stepID, loop.Range, err)
}
}
return nil
}
// expandLoop expands a loop step into its constituent steps.
func expandLoop(step *Step) ([]*Step, error) {
return expandLoopWithVars(step, nil)
}
View on GitHub (pinned to 71377f2769)
Solutions
- Read the wrapped inner error from ParseCondition for the exact syntax problem
- Rewrite the until condition using the library's documented condition syntax
- Test the condition by calling ParseCondition directly before shipping the formula
- Simplify the condition (e.g. single comparison) to isolate the failing part
Example fix
# before loop: until: "count > " # after loop: until: "count > 5"
Defensive patterns
Strategy: validation
Validate before calling
func validateUntil(cond string) error {
if cond == "" {
return nil
}
_, err := formula.ParseCondition(cond)
return err
} Try / catch
steps, err := formula.ApplyLoops(steps)
if err != nil {
if strings.Contains(err.Error(), "invalid until condition") {
return fmt.Errorf("fix loop.until syntax: %w", err)
}
return err
} Prevention
- Call ParseCondition on every until condition as a preflight before loading formulas
- Keep until conditions to simple documented comparisons
- Beware YAML quoting that mangles the condition string
When it happens
Trigger: ApplyLoops encountering a LoopSpec with a non-empty Until string that ParseCondition cannot parse (malformed comparison, unknown operator, unbalanced quoting, empty operand).
Common situations: Typo in a condition like `items.count >` (missing operand); using shell-style syntax instead of the library's condition grammar; quoting issues in YAML that mangle the expression; referencing unsupported functions.
Related errors
- loop %q: max must be positive
- loop %q: invalid range %q: %w
- loop %q: range end (%d) is less than start (%d)
- applying control flow: %w
- formula %q not accessible: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/0dc92f19a54fb31b.
Report an issue: GitHub.