{"record":{"id":"ef25283718d6e899","repo":"thanos-io/thanos","slug":"converting-prom-matchers-to-storepb-matchers","errorCode":null,"errorMessage":"converting prom matchers to storepb matchers","messagePattern":"converting prom matchers to storepb matchers","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/query/querier.go","lineNumber":438,"sourceCode":"\t\tq.maxt,\n\t\taggrs,\n\t\twarns,\n\t)\n\n\treturn dedup.NewSeriesSet(set, hints.Func, q.deduplicationFunc), resp.seriesSetStats, nil\n}\n\n// LabelValues returns all potential values for a label name.\nfunc (q *querier) LabelValues(ctx context.Context, name string, hints *storage.LabelHints, matchers ...*labels.Matcher) ([]string, annotations.Annotations, error) {\n\tspan, ctx := tracing.StartSpan(ctx, \"querier_label_values\")\n\tdefer span.Finish()\n\n\t// TODO(bwplotka): Pass it using the SeriesRequest instead of relying on context.\n\tctx = context.WithValue(ctx, store.StoreMatcherKey, q.storeDebugMatchers)\n\n\tpbMatchers, err := storepb.PromMatchersToMatchers(matchers...)\n\tif err != nil {\n\t\treturn nil, nil, errors.Wrap(err, \"converting prom matchers to storepb matchers\")\n\t}\n\n\tif hints == nil {\n\t\thints = &storage.LabelHints{}\n\t}\n\n\treq := &storepb.LabelValuesRequest{\n\t\tLabel:                   name,\n\t\tPartialResponseStrategy: q.partialResponseStrategy,\n\t\tStart:                   q.mint,\n\t\tEnd:                     q.maxt,\n\t\tMatchers:                pbMatchers,\n\t\tLimit:                   int64(hints.Limit),\n\t}\n\n\tif q.isDedupEnabled() {\n\t\treq.WithoutReplicaLabels = q.replicaLabels\n\t}","sourceCodeStart":420,"sourceCodeEnd":456,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/query/querier.go#L420-L456","documentation":"LabelValues converts the caller's PromQL label matchers to storepb matchers before proxying the LabelValues RPC. PromMatchersToMatchers failing (unsupported matcher type/regex) is wrapped as 'converting prom matchers to storepb matchers'.","triggerScenarios":"Calling the storage API LabelValues with matchers that storepb cannot encode, e.g. non-standard match types produced by custom client code.","commonSituations":"Custom integrations constructing labels.Matcher programmatically with invalid regex; API clients posting unusual label match selectors.","solutions":["Validate matchers before calling LabelValues; restrict to =, !=, =~, !~","Test the regex compiles as RE2 and is representable in storepb","Log the wrapped cause to find the offending matcher","Update Thanos if a matcher type you need fails conversion"],"exampleFix":"// before\nm := labels.MustNewMatcher(labels.MatchNotRegexp, \"job\", \"(bad regex[\")\n// after\nm := labels.MustNewMatcher(labels.MatchNotRegexp, \"job\", \"other-.*\")","handlingStrategy":"validation","validationCode":"func validateMatchers(ms []*labels.Matcher) error {\n    for _, m := range ms {\n        if _, err := regexp.Compile(m.Value); err != nil {\n            return fmt.Errorf(\"matcher %s=%q invalid: %w\", m.Name, m.Value, err)\n        }\n    }\n    return nil\n}","typeGuard":"func safeMatcher(m *labels.Matcher) bool {\n    t := m.Type\n    return t == labels.MatchEqual || t == labels.MatchNotEqual ||\n        t == labels.MatchRegexp || t == labels.MatchNotRegexp\n}","tryCatchPattern":"vals, warns, err := q.LabelValues(ctx, name, hints, matchers...)\nif err != nil && strings.Contains(err.Error(), \"converting prom matchers\") {\n    return nil, fmt.Errorf(\"invalid label matchers: %w\", err)\n}","preventionTips":["Sanitize regex input from API consumers","Restrict to standard match types","Test matchers against Prometheus' parser before issuing"],"tags":["thanos","labels","matchers","conversion"],"backgroundTag":"invalid-argument-format","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}