gastownhall/beads · error

label only supports = operator

Error message

label only supports = operator

What it means

applyLabelFilter only accepts the equality operator for label comparisons. Any other operator (!=, contains, >, etc.) on the label field is rejected with this error. Note the field is substring/list based: `label = none` or an empty value maps to NoLabels (issues with no labels).

Source

Thrown at internal/query/evaluator.go:294

	if comp.Op != OpEquals {
		return fmt.Errorf("assignee only supports = operator")
	}
	if comp.Value == "" || strings.ToLower(comp.Value) == "none" || strings.ToLower(comp.Value) == "null" {
		filter.NoAssignee = true
	} else {
		filter.Assignee = &comp.Value
	}
	return nil
}

func (e *Evaluator) applyOwnerFilter(comp *ComparisonNode, filter *types.IssueFilter) error {
	// 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 {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use `label = <name>` for each label you want (they accumulate in filter.Labels)
  2. Express exclusion differently: fetch with label filters and negate in application code, or use predicate mode if `label != x` is supported there
  3. Split `label in (a,b)` into OR-ed `label = a OR label = b` clauses if the query grammar supports it

Example fix

// before
bd list 'label != bug'
// after
bd list 'label = bug'   // then invert results client-side, or use predicate mode
Defensive patterns

Strategy: validation

Validate before calling

// Ensure label comparisons use '=' only
if comp.Field == "label" && comp.Op != OpEquals {
	return fmt.Errorf("label supports only '='; got %s", comp.Op.String())
}

Type guard

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

Try / catch

if err := eval.applyComparison(comp, filter); err != nil {
	if strings.Contains(err.Error(), "label only supports = operator") {
		// rewrite query to label = <name> or fall back to predicate mode
	}
}

Prevention

When it happens

Trigger: A query like `label != bug`, `label contains urgent`, or `label ~ foo` is parsed into a ComparisonNode with comp.Op != OpEquals and routed through applyComparison to applyLabelFilter.

Common situations: Users assuming label supports exclusion (!=) like the type field does; queries copied from JQL/GitHub search syntax that allow `label != x`; typos such as `label in (a,b)`.

Related errors


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