{"record":{"id":"cf987ba17e642f8f","repo":"jaegertracing/jaeger","slug":"w-it-does-not-support-the-operator-q-cf987b","errorCode":null,"errorMessage":"%w: it does not support the operator %q","messagePattern":"%w: it does not support the operator %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/storage/v2/api/tracestore/shape.go","lineNumber":287,"sourceCode":"\tdefault:\n\t\treturn \"\", fmt.Errorf(\"%w: it compares %q against a string constant only\", ErrFilterUnsupported, name)\n\t}\n}\n\n// errNotADuration refuses a bound that is not a length of time. An untyped constant reaching here\n// was never read as a duration, which expression.ResolveConstants does on the way in, so the\n// refusal says that rather than blaming the spelling the caller wrote.\nfunc errNotADuration(name string, value expression.Expression) error {\n\tif constant, ok := value.(*expression.AnyValue); ok {\n\t\treturn fmt.Errorf(\"%w: the bound %q on %q was never read as a duration\",\n\t\t\tErrFilterInvalid, constant.Value, name)\n\t}\n\treturn fmt.Errorf(`%w: it compares %q against a duration such as \"2s\" only`,\n\t\tErrFilterUnsupported, name)\n}\n\nfunc errUnsupportedOperator(op expression.Operator) error {\n\treturn fmt.Errorf(\"%w: it does not support the operator %q\", ErrFilterUnsupported, op)\n}\n\nfunc errUnsupportedOperatorOn(op expression.Operator, name string) error {\n\treturn fmt.Errorf(\"%w: it does not support the operator %q on %q\", ErrFilterUnsupported, op, name)\n}\n\nfunc errRepeatedPredicateOn(name string) error {\n\treturn fmt.Errorf(\"%w: it can carry only one predicate on %q\", ErrFilterUnsupported, name)\n}\n","sourceCodeStart":269,"sourceCodeEnd":297,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/v2/api/tracestore/shape.go#L269-L297","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\n&expression.Call{Op: expression.OpOr, Args: []expression.Expression{predA, predB}}\n// after — issue two queries and merge\nq1 := params; q1.Filter = predA\nq2 := params; q2.Filter = predB\n// merge results of FindTraces(q1) and FindTraces(q2)","handlingStrategy":"validation","validationCode":"func isLegacyConjunction(f *expression.Call) bool {\n  switch f.Op {\n  case expression.OpOr, expression.OpNot:\n    return false\n  case expression.OpAnd:\n    for _, a := range f.Args { if _, ok := a.(*expression.Call); !ok { return false } }\n    return true\n  default:\n    return len(f.Args) == 2\n  }\n}","typeGuard":"func isSupportedRootOp(f *expression.Call) bool { return f.Op != expression.OpOr && f.Op != expression.OpNot }","tryCatchPattern":"legacy, err := params.ToLegacyShape()\nif errors.Is(err, tracestore.ErrFilterUnsupported) {\n  return nil, fmt.Errorf(\"backend supports only flat AND conjunctions; rewrite or split the query: %w\", err)\n}","preventionTips":["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"],"tags":["jaeger","tracestore","filter-unsupported","operator"],"backgroundTag":"unsupported-query-operator","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}