gastownhall/beads · error
invalid boolean value: %s
Error message
invalid boolean value: %s
What it means
Boolean fields (via buildBoolPredicate) accept only truthy/falsy literals: true/yes/1 and false/no/0 (case-insensitive). Any other value — including on/off, enabled, T/F, or a non-boolean token — triggers this error before the predicate is built.
Source
Thrown at internal/query/evaluator.go:1033
case OpEquals:
return func(i *types.Issue) bool { return i.SpecID == value }, nil
case OpNotEquals:
return func(i *types.Issue) bool { return i.SpecID != value }, nil
default:
return nil, fmt.Errorf("spec does not support %s operator", comp.Op.String())
}
}
func (e *Evaluator) buildBoolPredicate(comp *ComparisonNode, getter func(*types.Issue) bool) (func(*types.Issue) bool, error) {
val := strings.ToLower(comp.Value)
var boolVal bool
switch val {
case "true", "yes", "1":
boolVal = true
case "false", "no", "0":
boolVal = false
default:
return nil, fmt.Errorf("invalid boolean value: %s", comp.Value)
}
switch comp.Op {
case OpEquals:
return func(i *types.Issue) bool { return getter(i) == boolVal }, nil
case OpNotEquals:
return func(i *types.Issue) bool { return getter(i) != boolVal }, nil
default:
return nil, fmt.Errorf("boolean field does not support %s operator", comp.Op.String())
}
}
// Evaluate is a convenience function that parses and evaluates a query string.
func Evaluate(query string) (*QueryResult, error) {
return EvaluateAt(query, time.Now())
}
// EvaluateAt parses and evaluates a query string with a specific reference time.View on GitHub (pinned to 71377f2769)
Solutions
- Rewrite the value as true/false, yes/no, or 1/0 (case-insensitive).
- Trim quotes and whitespace around the value in the query string.
- Check the %s in the message to see exactly what token was received — often a shell-escaping artifact.
- Fix UI/script generators to emit canonical true/false for boolean query fields.
Example fix
// before bd list --query "pinned = on" // after bd list --query "pinned = true" // or yes / 1
Defensive patterns
Strategy: validation
Validate before calling
var boolLiterals = map[string]bool{
"true": true, "yes": true, "1": true,
"false": false, "no": false, "0": false,
}
func validBoolValue(v string) bool {
_, ok := boolLiterals[strings.ToLower(strings.TrimSpace(v))]
return ok
} Type guard
func asBoolLiteral(v string) (bool, bool) {
b, ok := boolLiterals[strings.ToLower(strings.TrimSpace(v))]
return b, ok
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid boolean value") {
return fmt.Errorf("use true/false, yes/no, or 1/0: %w", err)
} Prevention
- Normalize on/off or T/F inputs to true/false before query building
- Trim whitespace and quotes from user-supplied values
- Maintain an allowlist of boolean literals in UI dropdowns
- Test boolean query fields with all six accepted literals
When it happens
Trigger: Queries like `pinned = on`, `blocked = enabled`, or `ready = "TRUE "` (with stray characters); a boolean comparison whose right-hand side does not normalize to one of the six accepted literals.
Common situations: SQL habits (bit values 1/0 are fine, but TRUE/FALSE spelled as T/F are not); config-file style on/off values; extra quotes or whitespace surviving shell escaping; passing numbers other than 1/0.
Related errors
- dolt.shared-server must be "true" or "false", got %q
- dolt.debug must be "true" or "false", got %q
- unknown field: %s
- invalid status: %s
- priority must be between 0 and 4
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/1f33ffaa689fdfc1.
Report an issue: GitHub.