gastownhall/beads · error

NOT type only supports = operator

Error message

NOT type only supports = operator

What it means

NOT type in filter mode appends to filter.ExcludeTypes and is implemented only for exact equality. Any other operator on NOT type raises this error. The parsed value becomes an IssueType added to the exclusion list.

Source

Thrown at internal/query/evaluator.go:599

// applyNot applies a NOT expression to the filter.
func (e *Evaluator) applyNot(not *NotNode, filter *types.IssueFilter) error {
	comp, ok := not.Operand.(*ComparisonNode)
	if !ok {
		return fmt.Errorf("NOT only supports simple comparisons in filter mode")
	}

	switch comp.Field {
	case "status":
		if comp.Op != OpEquals {
			return fmt.Errorf("NOT status only supports = operator")
		}
		status := types.Status(strings.ToLower(comp.Value))
		filter.ExcludeStatus = append(filter.ExcludeStatus, status)
		return nil
	case "type":
		if comp.Op != OpEquals {
			return fmt.Errorf("NOT type only supports = operator")
		}
		issueType := types.IssueType(strings.ToLower(comp.Value))
		filter.ExcludeTypes = append(filter.ExcludeTypes, issueType)
		return nil
	default:
		return fmt.Errorf("NOT not supported for field %s in filter mode", comp.Field)
	}
}

// parseTimeValue parses a time value from a comparison node.
// Supports duration values (7d, 24h) which are interpreted as "now - duration".
func (e *Evaluator) parseTimeValue(comp *ComparisonNode) (time.Time, error) {
	if comp.ValueType == TokenDuration {
		// Duration values like 7d mean "7 days ago" for < comparisons
		// and "within the last 7 days" for > comparisons
		// We parse as relative to now, going backwards
		return e.parseDurationAgo(comp.Value)
	}

View on GitHub (pinned to 71377f2769)

Solutions

  1. Use `NOT type=bug` to exclude the bug type
  2. Replace double negation: `NOT type!=bug` means `type=bug`
  3. For regex/type-set matching use positive `type=~...` or `type IN (...)` without NOT
  4. Chain multiple `NOT type=x` clauses to exclude several types

Example fix

// before
bd list 'NOT type!=bug'
// after
bd list 'type=bug'  # or NOT type=bug to exclude bugs
Defensive patterns

Strategy: validation

Validate before calling

if field == "type" && negated && op != "=" {
    return fmt.Errorf("NOT type requires = (got %s)", op)
}

Type guard

func notTypeValid(op string) bool { return op == "=" }

Prevention

When it happens

Trigger: A query like `NOT type!=bug` or `NOT type=~feat` hitting applyNot's type case with comp.Op != OpEquals.

Common situations: Double negation (`NOT type!=bug`); assuming type-matching operators carry over to the NOT path; scripted query builders pairing != with NOT.

Related errors


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