gastownhall/beads · error

id does not support %s operator

Error message

id does not support %s operator

What it means

The id field only supports the = and != operators. buildIDPredicate returns this error when a non-wildcard id value is compared with any other operator (>, <, >=, <=, contains, etc.), since ids have no meaningful ordering in this query language.

Source

Thrown at internal/query/evaluator.go:996

	hasWildcard := strings.HasSuffix(value, "*")
	if hasWildcard {
		prefix := strings.TrimSuffix(value, "*")
		switch comp.Op {
		case OpEquals:
			return func(i *types.Issue) bool { return strings.HasPrefix(i.ID, prefix) }, nil
		case OpNotEquals:
			return func(i *types.Issue) bool { return !strings.HasPrefix(i.ID, prefix) }, nil
		default:
			return nil, fmt.Errorf("id with wildcard only supports = and != operators")
		}
	}
	switch comp.Op {
	case OpEquals:
		return func(i *types.Issue) bool { return i.ID == value }, nil
	case OpNotEquals:
		return func(i *types.Issue) bool { return i.ID != value }, nil
	default:
		return nil, fmt.Errorf("id does not support %s operator", comp.Op.String())
	}
}

func (e *Evaluator) buildSpecPredicate(comp *ComparisonNode) (func(*types.Issue) bool, error) {
	value := comp.Value
	hasWildcard := strings.HasSuffix(value, "*")
	if hasWildcard {
		prefix := strings.TrimSuffix(value, "*")
		switch comp.Op {
		case OpEquals:
			return func(i *types.Issue) bool { return strings.HasPrefix(i.SpecID, prefix) }, nil
		case OpNotEquals:
			return func(i *types.Issue) bool { return !strings.HasPrefix(i.SpecID, prefix) }, nil
		default:
			return nil, fmt.Errorf("spec with wildcard only supports = and != operators")
		}
	}
	switch comp.Op {

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use exact match: id = bd-123, or exclusion: id != bd-123.
  2. For multiple ids, OR exact equality clauses: id = bd-1 OR id = bd-2.
  3. Use a prefix wildcard for a family of ids: id = bd-1* (with = only).
  4. Fix query-builder templates to restrict id comparisons to = and !=.

Example fix

// before
bd list --query "id > bd-100"
// after
bd list --query "id = bd-100*"   // or exact: id = bd-123
Defensive patterns

Strategy: validation

Validate before calling

func checkIDOperator(op Operator) error {
	if op != OpEquals && op != OpNotEquals {
		return fmt.Errorf("id supports only = and !=, got %s", op)
	}
	return nil
}

Type guard

func isIDEqualityQuery(op Operator) bool { return op == OpEquals || op == OpNotEquals }

Try / catch

if err := checkIDOperator(op); err != nil { return err } // before building the query
// or at runtime:
if err != nil && strings.Contains(err.Error(), "id does not support") {
	return fmt.Errorf("rewrite id clause with = or !=: %w", err)
}

Prevention

When it happens

Trigger: A query like `id > bd-123` or `id < bd-999` — a plain id value paired with an ordering operator.

Common situations: Template-driven query generation applying the same operators to every field; users expecting lexicographic id ranges to work; migration from another issue tracker whose query syntax allows id ranges.

Related errors


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