{"record":{"id":"887979ad91adfb20","repo":"jaegertracing/jaeger","slug":"w-it-does-not-index-the-q-level-887979","errorCode":null,"errorMessage":"%w: it does not index the %q level","messagePattern":"%w: it does not index the %q level","errorType":"validation","errorClass":"ErrFilterUnsupported","httpStatus":null,"severity":"error","filePath":"internal/storage/v2/api/tracestore/shape.go","lineNumber":184,"sourceCode":"\tif len(predicate.Args) != 2 {\n\t\treturn errUnsupportedOperator(predicate.Op)\n\t}\n\tswitch ref := predicate.Args[0].(type) {\n\tcase *expression.AttributeRef:\n\t\treturn applyAttribute(query, predicate.Op, ref, predicate.Args[1])\n\tcase *expression.FieldRef:\n\t\treturn applyField(query, predicate.Op, ref, predicate.Args[1])\n\tdefault:\n\t\treturn fmt.Errorf(\"%w: it compares a reference against a constant only\", ErrFilterUnsupported)\n\t}\n}\n\nfunc applyAttribute(query *TraceQueryParams, op expression.Operator, ref *expression.AttributeRef, value expression.Expression) error {\n\tif op != expression.OpEq {\n\t\treturn errUnsupportedOperatorOn(op, ref.Key)\n\t}\n\tif !legacyFilterLevels.SupportsLevel(ref.Level) {\n\t\treturn fmt.Errorf(\"%w: it does not index the %q level\", ErrFilterUnsupported, ref.Level)\n\t}\n\ttext, err := textConstant(ref.Key, value)\n\tif err != nil {\n\t\treturn err\n\t}\n\tif _, ok := query.Attributes.Get(ref.Key); ok {\n\t\treturn errRepeatedPredicateOn(ref.Key)\n\t}\n\tquery.Attributes.PutStr(ref.Key, text)\n\treturn nil\n}\n\n// applyField writes a predicate on a built-in field into the legacy field that holds it. Only\n// three of the built-ins have one, and a predicate on any of the others is refused.\nfunc applyField(query *TraceQueryParams, op expression.Operator, ref *expression.FieldRef, value expression.Expression) error {\n\tswitch {\n\tcase isField(ref, expression.LevelResource, expression.ResourceFieldService):\n\t\treturn applyText(&query.ServiceName, op, ref.Name, value)","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/internal/storage/v2/api/tracestore/shape.go#L166-L202","documentation":"applyAttribute converts an equality predicate on an AttributeRef into the legacy query's attribute map, but only if the legacyFilterLevels capability set indexes the attribute's level. A reference to a non-indexed level (e.g. trace-level attribute where only span/span-attribute are indexed) yields ErrFilterUnsupported with the level name.","triggerScenarios":"Calling ToLegacyShape with an Eq predicate whose AttributeRef has a Level outside legacyFilterLevels, and the operator is Eq (non-Eq fails earlier via errUnsupportedOperatorOn).","commonSituations":"Filters referencing trace-level or field-level attributes being downgraded to legacy TraceQueryParams; backend migrations where legacy stores never indexed the referenced level.","solutions":["Reference attributes at a level the legacy shape supports (span attributes).","Keep the filter-based query path for levels the legacy shape cannot express.","Pre-check ref.Level against legacyFilterLevels.SupportsLevel before converting."],"exampleFix":"// before\nexpression.Eq(expression.TraceAttribute(\"env\"), expression.Constant(\"prod\"))\n// after\nexpression.Eq(expression.SpanAttribute(\"env\"), expression.Constant(\"prod\"))","handlingStrategy":"validation","validationCode":"if !legacyFilterLevels.SupportsLevel(ref.Level) {\n  return fmt.Errorf(\"level %q not supported by legacy shape\", ref.Level)\n}","typeGuard":"func legacyIndexable(ref *expression.AttributeRef) bool {\n  return legacyFilterLevels.SupportsLevel(ref.Level)\n}","tryCatchPattern":"shape, err := tracestore.ToLegacyShape(filter)\nif err != nil {\n  if errors.Is(err, tracestore.ErrFilterUnsupported) && strings.Contains(err.Error(), \"level\") {\n    return queryViaFilterPath(filter) // legacy shape cannot express it\n  }\n  return err\n}","preventionTips":["Prefer span-attribute level for legacy-compatible filters.","Check SupportsLevel before emitting each predicate in builders.","Fall back to the filter query path when levels exceed legacy support."],"tags":["filter","shape","tracestore"],"backgroundTag":"unsupported-filter-level","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}