gastownhall/beads · error

invalid start expression: %w

Error message

invalid start expression: %w

What it means

After splitting the range on '..' and substituting variable placeholders, ValidateRange tokenizes the start expression to prove it is syntactically valid. A tokenize failure is wrapped with this error, so the cause is an underlying 'invalid number' or 'unexpected character' error from the tokenizer.

Source

Thrown at internal/formula/range.go:371

	}

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

	// Check that expressions parse (with placeholder vars)
	placeholderVars := make(map[string]string)
	rangeVarPattern.ReplaceAllStringFunc(expr, func(match string) string {
		name := match[1 : len(match)-1]
		placeholderVars[name] = "1" // Use 1 as placeholder
		return "1"
	})

	startExpr := strings.TrimSpace(m[1])
	startExpr = substituteVars(startExpr, placeholderVars)
	if _, err := tokenize(startExpr); err != nil {
		return fmt.Errorf("invalid start expression: %w", err)
	}

	endExpr := strings.TrimSpace(m[2])
	endExpr = substituteVars(endExpr, placeholderVars)
	if _, err := tokenize(endExpr); err != nil {
		return fmt.Errorf("invalid end expression: %w", err)
	}

	return nil
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Fix the start expression indicated by the wrapped tokenizer error (see %w cause)
  2. Use valid variable syntax like {name} so placeholders are substituted to numbers
  3. Test the start expression standalone with EvaluateExpr

Example fix

// before
ValidateRange("1.2.3..10")
// after
ValidateRange("1.2..10")
Defensive patterns

Strategy: validation

Validate before calling

// after variable substitution, ensure endpoints tokenize cleanly
sub := substituteVars(startExpr, vars)
if _, err := tokenize(sub); err != nil {
    return fmt.Errorf("bad start endpoint: %w", err)
}

Try / catch

if err := ValidateRange(expr); err != nil {
    var cause error = err
    if unwrapped := errors.Unwrap(err); unwrapped != nil { cause = unwrapped }
    // inspect cause for 'invalid number' / 'unexpected character'
}

Prevention

When it happens

Trigger: ValidateRange with a malformed start endpoint, e.g. 'range 1.2.3..10' or '1..10' where the start contains an illegal character like 'a..10' (if 'a' is not a valid variable).

Common situations: Variables in the start expression that don't match rangeVarPattern so they aren't substituted and remain raw identifiers the tokenizer rejects; typos in the start value.

Related errors


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