{"record":{"id":"7d1b80857034cb24","repo":"thanos-io/thanos","slug":"parse-metric-selector-v","errorCode":null,"errorMessage":"parse metric selector %v","messagePattern":"parse metric selector (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/block/metadata/meta.go","lineNumber":152,"sourceCode":"\t}\n\treturn v, nil\n}\n\ntype Rewrite struct {\n\t// ULIDs of all source head blocks that went into the block.\n\tSources []ulid.ULID `json:\"sources,omitempty\"`\n\t// Deletions if applied (in order).\n\tDeletionsApplied []DeletionRequest `json:\"deletions_applied,omitempty\"`\n\t// Relabels if applied.\n\tRelabelsApplied []*relabel.Config `json:\"relabels_applied,omitempty\"`\n}\n\ntype Matchers []*labels.Matcher\n\nfunc (m *Matchers) UnmarshalYAML(value *yaml.Node) (err error) {\n\t*m, err = extpromql.ParseMetricSelector(value.Value)\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"parse metric selector %v\", value.Value)\n\t}\n\treturn nil\n}\n\ntype DeletionRequest struct {\n\tMatchers  Matchers             `json:\"matchers\" yaml:\"matchers\"`\n\tIntervals tombstones.Intervals `json:\"intervals,omitempty\" yaml:\"intervals,omitempty\"`\n\tRequestID string               `json:\"request_id,omitempty\" yaml:\"request_id,omitempty\"`\n}\n\ntype File struct {\n\tRelPath string `json:\"rel_path\"`\n\t// SizeBytes is optional (e.g meta.json does not show size).\n\tSizeBytes int64 `json:\"size_bytes,omitempty\"`\n\n\t// Hash is an optional hash of this file. Used for potentially avoiding an extra download.\n\tHash *ObjectHash `json:\"hash,omitempty\"`\n}","sourceCodeStart":134,"sourceCodeEnd":170,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/block/metadata/meta.go#L134-L170","documentation":"Matchers.UnmarshalYAML parses a YAML node's string value as a Prometheus metric selector via extpromql.ParseMetricSelector. This error wraps the PromQL parser failure when the selector text is not a valid instant-vector selector, e.g. missing braces, bad label matcher syntax, or invalid label names/values. It is thrown while decoding M3 namespace deletion requests or other YAML config that embeds Matchers fields.","triggerScenarios":"Submitting a DeletionRequest (or any YAML config with a matchers field) where a matcher string like 'foo{bar=\"baz\"' or 'foo=' fails to parse as a PromQL selector; unquoted YAML values containing characters YAML mangles (e.g. braces or quotes); empty selector strings.","commonSituations":"Operators writing m3ctl deletion requests by hand and misplacing quotes/braces; YAML interpreting special characters (\", {, :) so the value seen by the parser differs from intent; using metric names or label names that violate Prometheus naming rules; copying selectors from PromQL range queries (with [5m]) into a field that only accepts instant selectors.","solutions":["Validate the selector string in promtool or a Prometheus query first (e.g. 'promtool check ...' or test in the Prometheus UI) and fix syntax errors — unbalanced braces/quotes are the most common cause.","Quote the YAML value: use matchers: ['foo{bar=\"baz\"}'] so YAML does not strip or reinterpret braces and quotes.","Ensure the string is a bare instant-vector selector (no range [5m], no offset, no functions/operators).","Check label and metric names against Prometheus naming rules ([a-zA-Z_:][a-zA-Z0-9_:]* for names).","Use the JSON API field instead of YAML if quoting is error-prone: {\"matchers\": [{\"type\":\"=\"\",\"name\":\"bar\",\"value\":\"baz\"}]}."],"exampleFix":"// before: YAML unquotes value, parser sees foo{bar=\"baz\" without quotes\nmatchers:\n  - foo{bar=\"baz\"}\n\n// after: explicitly quoted single-line selector\nmatchers:\n  - 'foo{bar=\"baz\"}'","handlingStrategy":"validation","validationCode":"import \"github.com/m3db/m3/src/query/util/exec\"\n// or validate with promql parser before submitting:\nif _, err := extpromql.ParseMetricSelector(selector); err != nil {\n    return fmt.Errorf(\"invalid selector %q: %w\", selector, err)\n}","typeGuard":"func isValidSelector(s string) bool {\n    _, err := extpromql.ParseMetricSelector(s)\n    return err == nil\n}","tryCatchPattern":"var m metadata.Matchers\nif err := yaml.Unmarshal(cfg, &m); err != nil {\n    if strings.Contains(err.Error(), \"parse metric selector\") {\n        return fmt.Errorf(\"bad matchers in config: %w\", err)\n    }\n    return err\n}","preventionTips":["Quote selector strings in YAML with single quotes so braces/quotes survive YAML parsing.","Validate selectors with promtool or the Prometheus UI before putting them in config.","Use only instant-vector selectors — no ranges, offsets, or functions — in Matchers fields.","Prefer the JSON API matcher objects (type/name/value) when generating requests programmatically."],"tags":["promql","yaml","configuration","validation"],"backgroundTag":"invalid-regex-pattern","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"}