gastownhall/beads · error
NOT only supports simple comparisons in filter mode
Error message
NOT only supports simple comparisons in filter mode
What it means
In filter mode, NOT is translated into IssueFilter exclusion lists (ExcludeStatus, ExcludeTypes), which only exist for simple equality comparisons. applyNot type-asserts not.Operand to *ComparisonNode; if the operand is any other node (AND/OR group, nested NOT, etc.) the assertion fails and this error is returned. Nested or compound NOT expressions require predicate mode.
Source
Thrown at internal/query/evaluator.go:586
}
return func(i *types.Issue) bool {
if len(i.Metadata) == 0 {
return false
}
var data map[string]json.RawMessage
if err := json.Unmarshal(i.Metadata, &data); err != nil {
return false
}
_, ok := data[key]
return ok
}, nil
}
// applyNot applies a NOT expression to the filter.
func (e *Evaluator) applyNot(not *NotNode, filter *types.IssueFilter) error {
comp, ok := not.Operand.(*ComparisonNode)
if !ok {
return fmt.Errorf("NOT only supports simple comparisons in filter mode")
}
switch comp.Field {
case "status":
if comp.Op != OpEquals {
return fmt.Errorf("NOT status only supports = operator")
}
status := types.Status(strings.ToLower(comp.Value))
filter.ExcludeStatus = append(filter.ExcludeStatus, status)
return nil
case "type":
if comp.Op != OpEquals {
return fmt.Errorf("NOT type only supports = operator")
}
issueType := types.IssueType(strings.ToLower(comp.Value))
filter.ExcludeTypes = append(filter.ExcludeTypes, issueType)
return nil
default:View on GitHub (pinned to 71377f2769)
Solutions
- Rewrite the query so NOT wraps a single field comparison, e.g. `NOT status=open`
- Push the negation inward manually: `NOT (a OR b)` is generally not expressible; enumerate the exclusions instead, e.g. `NOT status=open NOT status=closed`
- Avoid nested NOT; `NOT NOT x` is not supported in filter mode
- If you need compound negation, run separate queries and combine results in a script
Example fix
// before bd list 'NOT (status=open OR priority=1)' // after bd list 'NOT status=open NOT priority=1' # simple comparisons only in filter mode
Defensive patterns
Strategy: validation
Validate before calling
// NOT must wrap a single field=value comparison in filter mode
func notClauseValid(operandField, operandOp string) bool {
switch operandField {
case "status", "type":
return operandOp == "="
default:
return false
}
} Type guard
func isSimpleComparison(n Node) (*ComparisonNode, bool) {
comp, ok := n.(*ComparisonNode)
return comp, ok
} Try / catch
result, err := eval.Evaluate(expr)
if err != nil {
var nodeErr *NodeError
if strings.Contains(err.Error(), "NOT only supports simple comparisons") {
// rewrite query without compound NOT or fall back to client-side filtering
}
return result, err
} Prevention
- Wrap NOT only around single field comparisons
- Never nest NOT or wrap NOT around AND/OR groups in filter mode
- Enumerate exclusions as multiple NOT status=x / NOT type=x clauses
- For compound negation, combine query results in a script
When it happens
Trigger: Queries like `NOT (status=open OR priority=1)` or `NOT NOT status=open` where the NOT operand is not a single ComparisonNode, called from buildFilter or extractBaseFilters.
Common situations: Writing boolean-algebra style queries assuming full NOT generality; wrapping a group in NOT to 'invert' a complex clause; tools generating queries programmatically emitting NOT around compound expressions.
Related errors
- NOT status only supports = operator
- NOT type only supports = operator
- NOT not supported for field %s in filter mode
- ErrQuery
- failed to search issues: %w
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/42a2dc0ce47fdb55.
Report an issue: GitHub.