gastownhall/beads · error

title only supports = operator (use title contains pattern)

Error message

title only supports = operator (use title contains pattern)

What it means

applyTitleFilter supports only the = operator; the match is implemented as a substring check via filter.TitleContains. Any other operator on title is rejected. The error message itself points to the intended alternative: `title contains pattern` style queries belong in predicate mode.

Source

Thrown at internal/query/evaluator.go:306

	// Owner filtering requires predicate
	return fmt.Errorf("owner filtering requires predicate mode")
}

func (e *Evaluator) applyLabelFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
	if comp.Op != OpEquals {
		return fmt.Errorf("label only supports = operator")
	}
	if comp.Value == "" || strings.ToLower(comp.Value) == "none" || strings.ToLower(comp.Value) == "null" {
		filter.NoLabels = true
	} else {
		filter.Labels = append(filter.Labels, comp.Value)
	}
	return nil
}

func (e *Evaluator) applyTitleFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
	if comp.Op != OpEquals {
		return fmt.Errorf("title only supports = operator (use title contains pattern)")
	}
	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 {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use `title = <substring>` which sets TitleContains (substring match) in filter mode
  2. Switch to predicate mode where title contains/other operators are supported via buildTitlePredicate
  3. Pre-filter by other fields and apply title matching in application code

Example fix

// before
bd list 'title contains flaky'
// after
bd list 'title = flaky'
Defensive patterns

Strategy: validation

Validate before calling

// Validate title comparisons before evaluation
if comp.Field == "title" && comp.Op != OpEquals {
	return fmt.Errorf("use 'title = <substring>' in filter mode")
}

Type guard

func titleOpSupported(op Op) bool { return op == OpEquals }

Try / catch

if err := eval.applyComparison(comp, filter); err != nil {
	var _ *UnsupportedOpError
	if strings.Contains(err.Error(), "title only supports = operator") {
		// rewrite to title = <substring> or switch to predicate mode
	}
}

Prevention

When it happens

Trigger: Queries like `title contains foo`, `title != bar`, or `title ~ x` hit applyTitleFilter with comp.Op != OpEquals and fail. Only bare `title = something` succeeds (and behaves as a contains match).

Common situations: Users writing natural-language-ish searches (`title contains login bug`) that the filter-mode evaluator does not implement; regex-style title matching assumptions; queries ported from other issue trackers.

Related errors


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