{"record":{"id":"aaf0855e66785e45","repo":"thanos-io/thanos","slug":"expected-type-parser-vectorselector-got-t","errorCode":null,"errorMessage":"expected type *parser.VectorSelector, got %T","messagePattern":"expected type \\*parser\\.VectorSelector, got %T","errorType":"error_code","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/extpromql/parser.go","lineNumber":40,"sourceCode":"\tmaps.Copy(allFuncs, parse.XFunctions)\n\tp := parser.NewParser(input, parser.WithFunctions(allFuncs))\n\tdefer p.Close()\n\treturn p.ParseExpr()\n}\n\n// ParseMetricSelector parses the provided textual metric selector into a list of\n// label matchers.\nfunc ParseMetricSelector(input string) ([]*labels.Matcher, error) {\n\texpr, err := ParseExpr(input)\n\t// because of the AST checking present in the ParseExpr function,\n\t// we need to ignore the error if it is just the check for empty name matcher.\n\tif err != nil && !isEmptyNameMatcherErr(err) {\n\t\treturn nil, err\n\t}\n\n\tvs, ok := expr.(*parser.VectorSelector)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"expected type *parser.VectorSelector, got %T\", expr)\n\t}\n\n\treturn vs.LabelMatchers, nil\n}\n\nfunc isEmptyNameMatcherErr(err error) bool {\n\tvar parseErrs parser.ParseErrors\n\tif errors.As(err, &parseErrs) {\n\t\treturn len(parseErrs) == 1 &&\n\t\t\tstrings.HasSuffix(parseErrs[0].Error(), \"vector selector must contain at least one non-empty matcher\")\n\t}\n\n\treturn false\n}\n","sourceCodeStart":22,"sourceCodeEnd":55,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/extpromql/parser.go#L22-L55","documentation":"ParseMetricSelector parses a PromQL expression and then asserts that the resulting AST node is a *parser.VectorSelector so it can return the label matchers. If the parsed expression is any other node type (aggregate, matrix selector, binary expression, etc.), this type-assertion error is returned.","triggerScenarios":"Passing a non-instant-vector selector expression to ParseMetricSelector via ParseStore, parseMatchersParam, parseStoreDebugMatchersParam, or UnmarshalYAML — e.g. 'sum(rate(foo[5m]))', 'foo[5m]', 'up + 1', or a scalar.","commonSituations":"Store --selector and rule matchers configs that accidentally contain full PromQL queries instead of bare metric selectors; users copying dashboard queries into matcher fields.","solutions":["Use a bare instant-vector selector expression, e.g. 'up{job=\"prometheus\"}'.","Remove aggregation functions, [range] selectors, and operators from the expression.","Pre-validate the string matches a metric-selector shape (optional metric name plus {} label matchers)."],"exampleFix":"// before\nParseMetricSelector(\"sum(rate(http_requests_total[5m]))\")\n// after\nParseMetricSelector(\"http_requests_total\")","handlingStrategy":"validation","validationCode":"func looksLikeSelector(s string) bool {\n  return !strings.ContainsAny(s, \"+\") && !strings.Contains(s, \"[\") &&\n    !strings.HasPrefix(s, \"sum(\") && !strings.HasPrefix(s, \"rate(\")\n}","typeGuard":"expr, ok := parsed.(*parser.VectorSelector)\nif !ok { return fmt.Errorf(\"not a vector selector\") }","tryCatchPattern":"ms, err := extpromql.ParseMetricSelector(q)\nif err != nil { return nil, fmt.Errorf(\"store selector must be a bare metric selector: %w\", err) }","preventionTips":["Only pass bare instant-vector selectors like 'metric{labels}' to matcher/selector fields","Keep dashboard queries out of --selector flags","Unit-test config parsing with representative user input"],"tags":["promql","type-mismatch","validation"],"backgroundTag":"incompatible-source-type","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"}