jaegertracing/jaeger · error
%w: it does not support the operator %q
Error message
%w: it does not support the operator %q
What it means
Downconverting a filter to the legacy scalar shape can only express a flat conjunction of equality/comparison predicates. The logical operators `or` and `not` have no legacy form, and a conjunction argument that is not a predicate call (wrong arity) cannot be interpreted, so flatConjuncts / applyAsLegacyField refuse the operator with ErrFilterUnsupported and the operator's name. This is a static expressiveness limit, not a transient fault.
Source
Thrown at internal/storage/v2/api/tracestore/shape.go:287
default:
return "", fmt.Errorf("%w: it compares %q against a string constant only", ErrFilterUnsupported, name)
}
}
// errNotADuration refuses a bound that is not a length of time. An untyped constant reaching here
// was never read as a duration, which expression.ResolveConstants does on the way in, so the
// refusal says that rather than blaming the spelling the caller wrote.
func errNotADuration(name string, value expression.Expression) error {
if constant, ok := value.(*expression.AnyValue); ok {
return fmt.Errorf("%w: the bound %q on %q was never read as a duration",
ErrFilterInvalid, constant.Value, name)
}
return fmt.Errorf(`%w: it compares %q against a duration such as "2s" only`,
ErrFilterUnsupported, name)
}
func errUnsupportedOperator(op expression.Operator) error {
return fmt.Errorf("%w: it does not support the operator %q", ErrFilterUnsupported, op)
}
func errUnsupportedOperatorOn(op expression.Operator, name string) error {
return fmt.Errorf("%w: it does not support the operator %q on %q", ErrFilterUnsupported, op, name)
}
func errRepeatedPredicateOn(name string) error {
return fmt.Errorf("%w: it can carry only one predicate on %q", ErrFilterUnsupported, name)
}
View on GitHub (pinned to 806f444784)
Solutions
- Split the query into multiple requests and union the results client-side instead of using OR/NOT.
- Restrict the filter builder to conjunctions of two-argument predicates when targeting legacy-only backends.
- Use a Reader/backend with native filter support so the filter is not downconverted.
Example fix
// before
&expression.Call{Op: expression.OpOr, Args: []expression.Expression{predA, predB}}
// after — issue two queries and merge
q1 := params; q1.Filter = predA
q2 := params; q2.Filter = predB
// merge results of FindTraces(q1) and FindTraces(q2) Defensive patterns
Strategy: validation
Validate before calling
func isLegacyConjunction(f *expression.Call) bool {
switch f.Op {
case expression.OpOr, expression.OpNot:
return false
case expression.OpAnd:
for _, a := range f.Args { if _, ok := a.(*expression.Call); !ok { return false } }
return true
default:
return len(f.Args) == 2
}
} Type guard
func isSupportedRootOp(f *expression.Call) bool { return f.Op != expression.OpOr && f.Op != expression.OpNot } Try / catch
legacy, err := params.ToLegacyShape()
if errors.Is(err, tracestore.ErrFilterUnsupported) {
return nil, fmt.Errorf("backend supports only flat AND conjunctions; rewrite or split the query: %w", err)
} Prevention
- Build only AND-of-predicates filters for legacy-only backends
- Keep every predicate call at exactly two arguments
- Detect OR/NOT needs early and plan multi-query fan-out
When it happens
Trigger: ToLegacyShape() is given a Filter whose root call is OpOr or OpNot; or a conjunction contains a non-*expression.Call argument; or a predicate has an argument count other than 2 (arity mismatch surfaced against its Op).
Common situations: A UI builds (a OR b) searches against a backend that only supports legacy conjunctive filters; a hand-rolled Call with a single argument reaches the converter; a generic filter DSL feature outpaces backend legacy capabilities.
Related errors
- %w: it does not support the operator %q on %q
- %w: it does not support the built-in field %q of the %q leve
- %w: it compares %q against a string constant only
- %w: it compares %q against a duration such as "2s" only
- %w: it can carry only one predicate on %q
AI-assisted analysis of jaegertracing/jaeger@806f444784 (2026-09-01).
Data as JSON: /api/errors/cf987ba17e642f8f.
Report an issue: GitHub.