gastownhall/beads · error
notes only supports = operator
Error message
notes only supports = operator
What it means
applyNotesFilter only permits the = operator on the notes field, implemented as a substring match via filter.NotesContains. Any other operator is rejected. Unlike assignee/label/description, notes has no special 'none' handling — the raw value (even empty) becomes NotesContains.
Source
Thrown at internal/query/evaluator.go:326
filter.TitleContains = comp.Value
return nil
}
func (e *Evaluator) applyDescriptionFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
if comp.Op != OpEquals {
return fmt.Errorf("description only supports = operator (use desc contains pattern)")
}
if comp.Value == "" || strings.ToLower(comp.Value) == "none" || strings.ToLower(comp.Value) == "null" {
filter.EmptyDescription = true
} else {
filter.DescriptionContains = comp.Value
}
return nil
}
func (e *Evaluator) applyNotesFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
if comp.Op != OpEquals {
return fmt.Errorf("notes only supports = operator")
}
filter.NotesContains = comp.Value
return nil
}
func (e *Evaluator) applyCreatedFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
t, err := e.parseTimeValue(comp)
if err != nil {
return fmt.Errorf("invalid created time: %w", err)
}
switch comp.Op {
case OpEquals:
// For equals, set both before and after to bracket the day
dayStart := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, t.Location())
dayEnd := dayStart.Add(24 * time.Hour)
filter.CreatedAfter = &dayStart
filter.CreatedBefore = &dayEnd
case OpGreater:View on GitHub (pinned to 71377f2769)
Solutions
- Use `notes = <substring>` in filter mode (substring match)
- Use predicate mode where notes contains / other operators are supported via buildNotesPredicate
- Exclude notes matches by post-filtering results in application code
Example fix
// before bd list 'notes contains escalated' // after bd list 'notes = escalated'
Defensive patterns
Strategy: validation
Validate before calling
// Validate notes comparisons before evaluation
if comp.Field == "notes" && comp.Op != OpEquals {
return fmt.Errorf("use 'notes = <substring>' in filter mode")
} Type guard
func notesOpSupported(op Op) bool { return op == OpEquals } Try / catch
if err := eval.applyComparison(comp, filter); err != nil {
if strings.Contains(err.Error(), "notes only supports = operator") {
// rewrite to notes = <substring> or use predicate mode
}
} Prevention
- Always use `notes = <substring>` (implemented as contains)
- Use predicate mode for non-equality notes operators
- Post-filter note exclusions in application code instead of using !=
When it happens
Trigger: Queries like `notes != x`, `notes contains foo`, or `notes ~ y` reach applyNotesFilter with comp.Op != OpEquals and return this error.
Common situations: Users searching agent/audit notes with contains syntax; attempts to exclude issues mentioning a string via !=; queries modeled on the predicate-mode notes API.
Related errors
- owner filtering requires predicate mode
- label only supports = operator
- title only supports = operator (use title contains pattern)
- description only supports = operator (use desc contains patt
- OR not supported for this field combination
AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30).
Data as JSON: /api/errors/51877394aa4199f7.
Report an issue: GitHub.