thanos-io/thanos · error
expected type *parser.VectorSelector, got %T
Error message
expected type *parser.VectorSelector, got %T
What it means
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.
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).
Example fix
// before
ParseMetricSelector("sum(rate(http_requests_total[5m]))")
// after
ParseMetricSelector("http_requests_total") Defensive patterns
Strategy: validation
Validate before calling
func looksLikeSelector(s string) bool {
return !strings.ContainsAny(s, "+") && !strings.Contains(s, "[") &&
!strings.HasPrefix(s, "sum(") && !strings.HasPrefix(s, "rate(")
} Type guard
expr, ok := parsed.(*parser.VectorSelector)
if !ok { return fmt.Errorf("not a vector selector") } Try / catch
ms, err := extpromql.ParseMetricSelector(q)
if err != nil { return nil, fmt.Errorf("store selector must be a bare metric selector: %w", err) } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Store --selector and rule matchers configs that accidentally contain full PromQL queries instead of bare metric selectors; users copying dashboard queries into matcher fields.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- parse metric selector
- parser ParseMetricSelector
- unsupported format for label
- --auto-gomemlimit.ratio must be greater than 0 and less…
- unexpected downsampling resolution
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/aaf0855e66785e45.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/extpromql/parser.go:40
maps.Copy(allFuncs, parse.XFunctions)
p := parser.NewParser(input, parser.WithFunctions(allFuncs))
defer p.Close()
return p.ParseExpr()
}
// ParseMetricSelector parses the provided textual metric selector into a list of
// label matchers.
func ParseMetricSelector(input string) ([]*labels.Matcher, error) {
expr, err := ParseExpr(input)
// because of the AST checking present in the ParseExpr function,
// we need to ignore the error if it is just the check for empty name matcher.
if err != nil && !isEmptyNameMatcherErr(err) {
return nil, err
}
vs, ok := expr.(*parser.VectorSelector)
if !ok {
return nil, fmt.Errorf("expected type *parser.VectorSelector, got %T", expr)
}
return vs.LabelMatchers, nil
}
func isEmptyNameMatcherErr(err error) bool {
var parseErrs parser.ParseErrors
if errors.As(err, &parseErrs) {
return len(parseErrs) == 1 &&
strings.HasSuffix(parseErrs[0].Error(), "vector selector must contain at least one non-empty matcher")
}
return false
}
View on GitHub (pinned to 35b8b99117)