gastownhall/beads · error

unexpected operator: %s

Error message

unexpected operator: %s

What it means

After successfully parsing the priority value, buildPriorityPredicate switches on the operator. Equality, inequality, and all four ordering operators are supported; anything else reaches the default case and returns this error. Practically this means the operator token was not recognized by the parser or is invalid for this field.

Source

Thrown at internal/query/evaluator.go:769

	priority, err := strconv.Atoi(comp.Value)
	if err != nil {
		return nil, fmt.Errorf("invalid priority: %s", comp.Value)
	}
	switch comp.Op {
	case OpEquals:
		return func(i *types.Issue) bool { return i.Priority == priority }, nil
	case OpNotEquals:
		return func(i *types.Issue) bool { return i.Priority != priority }, nil
	case OpLess:
		return func(i *types.Issue) bool { return i.Priority < priority }, nil
	case OpLessEq:
		return func(i *types.Issue) bool { return i.Priority <= priority }, nil
	case OpGreater:
		return func(i *types.Issue) bool { return i.Priority > priority }, nil
	case OpGreaterEq:
		return func(i *types.Issue) bool { return i.Priority >= priority }, nil
	default:
		return nil, fmt.Errorf("unexpected operator: %s", comp.Op.String())
	}
}

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

func (e *Evaluator) buildAssigneePredicate(comp *ComparisonNode) (func(*types.Issue) bool, error) {
	value := comp.Value
	isNone := value == "" || strings.ToLower(value) == "none" || strings.ToLower(value) == "null"

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use a supported operator: =, !=, <, <=, >, >=.
  2. Verify there is exactly one operator between field and value (`priority = 1`, not `priority 1`).
  3. If building queries programmatically, only pass the defined Op constants.

Example fix

// before
bd list --query "priority : 1"
// after
bd list --query "priority = 1"
Defensive patterns

Strategy: validation

Validate before calling

// Go: whitelist operators accepted for priority
var priorityOps = map[query.Op]bool{
    query.OpEquals: true, query.OpNotEquals: true,
    query.OpLess: true, query.OpLessEq: true,
    query.OpGreater: true, query.OpGreaterEq: true,
}
if !priorityOps[comp.Op] { return fmt.Errorf("unsupported priority operator %s", comp.Op) }

Try / catch

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

Prevention

When it happens

Trigger: A priority comparison with a malformed or non-comparison operator token, e.g. `priority 1`, or a custom/internal operator string that Op.String() renders but the priority switch does not handle.

Common situations: Missing the operator entirely in hand-written queries; using a symbol from another query dialect (e.g. `:`, `=~`); programmatic construction of ComparisonNode with an operator not in the standard set.

Related errors


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