gastownhall/beads · error

notes does not support %s operator

Error message

notes does not support %s operator

What it means

The `notes` field supports contains-style matching and NotEquals (both on the lowercased Notes string). Any other operator in a notes comparison reaches the default branch of buildNotesPredicate and returns this error.

Source

Thrown at internal/query/evaluator.go:900

		}, nil
	default:
		return nil, fmt.Errorf("description does not support %s operator", comp.Op.String())
	}
}

func (e *Evaluator) buildNotesPredicate(comp *ComparisonNode) (func(*types.Issue) bool, error) {
	value := strings.ToLower(comp.Value)
	switch comp.Op {
	case OpEquals:
		return func(i *types.Issue) bool {
			return strings.Contains(strings.ToLower(i.Notes), value)
		}, nil
	case OpNotEquals:
		return func(i *types.Issue) bool {
			return !strings.Contains(strings.ToLower(i.Notes), value)
		}, nil
	default:
		return nil, fmt.Errorf("notes does not support %s operator", comp.Op.String())
	}
}

func (e *Evaluator) buildCreatedPredicate(comp *ComparisonNode) (func(*types.Issue) bool, error) {
	t, err := e.parseTimeValue(comp)
	if err != nil {
		return nil, fmt.Errorf("invalid created time: %w", err)
	}
	return e.buildTimePredicate(comp.Op, t, func(i *types.Issue) time.Time { return i.CreatedAt })
}

func (e *Evaluator) buildUpdatedPredicate(comp *ComparisonNode) (func(*types.Issue) bool, error) {
	t, err := e.parseTimeValue(comp)
	if err != nil {
		return nil, fmt.Errorf("invalid updated time: %w", err)
	}
	return e.buildTimePredicate(comp.Op, t, func(i *types.Issue) time.Time { return i.UpdatedAt })
}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use the contains operator with a keyword expected in the notes.
  2. Use `!=` to exclude notes containing the text.
  3. For structured lookups, query another field (status, assignee, label) instead of notes.

Example fix

// before
bd list --query "notes = escalated"
// after
bd list --query "notes contains escalated"
Defensive patterns

Strategy: validation

Validate before calling

// Go: notes supports contains and != only
if !isContainsOp(comp.Op) && comp.Op != query.OpNotEquals {
    return fmt.Errorf("notes supports only contains and !=, got %s", comp.Op)
}

Try / catch

// Go
pred, err := e.buildComparisonPredicate(node)
if err != nil {
    return fmt.Errorf("notes filter invalid: %w", err)
}

Prevention

When it happens

Trigger: A query filter like `notes = "some note"` if equality is not handled, or `notes >= foo` — an operator outside the contains/not-equals set.

Common situations: Expecting exact-match semantics on notes text; carrying over operators from other text fields; assuming notes are indexed/searchable like full text in other tools.

Related errors


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