gastownhall/beads · error

evaluating range start %q: %w

Error message

evaluating range start %q: %w

What it means

ParseRange() matched the start..end structure but EvaluateExpr failed on the start expression, so the start side is not a valid arithmetic expression (after variable substitution). The failing start expression and the underlying evaluator error are wrapped for diagnosis.

Source

Thrown at internal/formula/range.go:60

func ParseRange(expr string, vars map[string]string) (*RangeSpec, error) {
	expr = strings.TrimSpace(expr)
	if expr == "" {
		return nil, fmt.Errorf("empty range expression")
	}

	// Parse start..end format
	m := rangePattern.FindStringSubmatch(expr)
	if m == nil {
		return nil, fmt.Errorf("invalid range format %q: expected start..end", expr)
	}

	startExpr := strings.TrimSpace(m[1])
	endExpr := strings.TrimSpace(m[2])

	// Evaluate start expression
	start, err := EvaluateExpr(startExpr, vars)
	if err != nil {
		return nil, fmt.Errorf("evaluating range start %q: %w", startExpr, err)
	}

	// Evaluate end expression
	end, err := EvaluateExpr(endExpr, vars)
	if err != nil {
		return nil, fmt.Errorf("evaluating range end %q: %w", endExpr, err)
	}

	return &RangeSpec{Start: start, End: end}, nil
}

// EvaluateExpr evaluates a mathematical expression with variable substitution.
// Supports: + - * / ^ (power) and parentheses.
// Variables use {name} syntax.
func EvaluateExpr(expr string, vars map[string]string) (int, error) {
	// Substitute variables first
	expr = substituteVars(expr, vars)

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix the start expression to a valid arithmetic expression, e.g. "1..10" or "2^{n}..10".
  2. Ensure every variable referenced in the start expression exists in the vars map passed to ParseRange.
  3. Read the inner wrapped error from EvaluateExpr — it names the exact evaluation problem (unknown var, bad token).

Example fix

# before
range: "{start}..10"   # start not in vars

# after
vars: { start: "1" }
range: "{start}..10"
Defensive patterns

Strategy: validation

Validate before calling

// Check that every {var} in the start expression exists before parsing.
for _, m := range varRefRe.FindAllStringSubmatch(startExpr, -1) {
	if _, ok := vars[m[1]]; !ok {
		return fmt.Errorf"undefined var %q in range start", m[1]
	}
}
if _, err := EvaluateExpr(startExpr, vars); err != nil {
	return fmt.Errorf"bad range start: %w", err
}

Try / catch

spec, err := ParseRange(expr, vars)
if err != nil {
	var evalErr error
	if errors.As(err, &evalErr) && strings.Contains(err.Error(), "evaluating range start") {
		// fix the start expression or its vars
	}
}

Prevention

When it happens

Trigger: ParseRange("a..10", vars) where variable 'a' is undefined in vars; a start expression with unsupported syntax (non-numeric tokens, unknown operators); unexpanded template placeholders like "{n}" with no matching var key.

Common situations: Loop range defined as "2^{n}..10" but var n missing from the expansion vars; typo in the variable name inside the start expression; locale/formatting issues leaving commas or units (e.g. "1,000") in the expression.

Related errors


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