jaegertracing/jaeger · error · ErrFilterUnsupported
%w: it does not support the operator %q
Error message
%w: it does not support the operator %q
What it means
FilterCapabilities.EnsureSupported recursively validates a filter expression against what a Reader declared it can evaluate. When the Reader's capability set does not include the operator used by a Call node in the filter, it returns ErrFilterUnsupported wrapped with the operator name.
Source
Thrown at internal/storage/v2/api/tracestore/admission.go:74
// caller's to settle first.
func (q TraceQueryParams) ForCapabilities(caps SearchCapabilities) (TraceQueryParams, error) {
if q.Filter == nil {
return q, nil
}
if caps.Filter.IsEmpty() {
return q.ToLegacyShape()
}
return q, caps.Filter.EnsureSupported(q.Filter)
}
// EnsureSupported walks the filter and refuses the first predicate the Reader did not declare it
// can evaluate.
func (c FilterCapabilities) EnsureSupported(filter *expression.Call) error {
if filter == nil {
return nil
}
if !c.SupportsOperator(filter.Op) {
return fmt.Errorf("%w: it does not support the operator %q", ErrFilterUnsupported, filter.Op)
}
for _, arg := range filter.Args {
var level expression.Level
switch term := arg.(type) {
case *expression.Call:
if err := c.EnsureSupported(term); err != nil {
return err
}
continue
case *expression.AttributeRef:
level = term.Level
case *expression.FieldRef:
level = term.Level
case *expression.NestedRef:
level = term.Level
default:
// A constant carries nothing a Reader has to support.
continueView on GitHub (pinned to 806f444784)
Solutions
- Query the Reader's filter capabilities and restrict the expression to supported operators.
- Rewrite unsupported operators into supported equivalents (e.g. ranges into explicit comparisons if supported).
- Pre-validate the filter with EnsureSupported before calling the Reader.
Example fix
// before
caps := reader.FilterCapabilities()
if err := caps.EnsureSupported(filter); err != nil { ... } // discover first
// after: build filter only from operators in caps
if !caps.SupportsOperator(expression.OpGt) { filter = rewriteToEq(filter) } Defensive patterns
Strategy: validation
Validate before calling
caps := reader.FilterCapabilities()
if err := caps.EnsureSupported(filter); err != nil {
return fmt.Errorf("filter unsupported by reader: %w", err)
} Try / catch
if err := reader.FindTraces(ctx, traces, q); err != nil {
if errors.Is(err, tracestore.ErrFilterUnsupported) {
filter = downgradeFilter(filter, caps) // rewrite to supported ops
}
} Prevention
- Always read FilterCapabilities before constructing filters.
- Write filter builders parameterized on the capability set.
- Unit-test filters against each backend's declared capabilities.
When it happens
Trigger: Passing a filter containing an operator (e.g. OpGt, OpRegex) to a Reader whose FilterCapabilities.SupportsOperator returns false for it — directly or nested inside an AND/NOT tree.
Common situations: Querying a backend (e.g. legacy-shape stores) that only supports equality with a filter using range or regex operators; capability discovery was skipped and the operator assumption was wrong.
Related errors
- %w: it does not index the %q level
- %w: it cannot be combined with %v; express those predicates
- %w: it evaluates a conjunction of predicates only
- %w: it compares a reference against a constant only
- %w: it does not index the %q level
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/73cd5d25532681e4.
Report an issue: GitHub.