{"record":{"id":"44fa05c8042399c1","repo":"thanos-io/thanos","slug":"failed-to-unmarshal-rulefmt-configruleadapter","errorCode":null,"errorMessage":"failed to unmarshal rulefmt.configRuleAdapter","messagePattern":"failed to unmarshal rulefmt\\.configRuleAdapter","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rules/manager.go","lineNumber":233,"sourceCode":"\trs := struct {\n\t\tRuleGroup rulefmt.RuleGroup `yaml:\",inline\"`\n\t\tStrategy  string            `yaml:\"partial_response_strategy\"`\n\t}{}\n\n\tif err := unmarshal(&rs); err != nil {\n\t\treturn err\n\t}\n\n\tg.PartialResponseStrategy = new(storepb.PartialResponseStrategy)\n\t// Same as YAMl. Quote as JSON unmarshal expects raw JSON field.\n\tif err := g.PartialResponseStrategy.UnmarshalJSON([]byte(\"\\\"\" + rs.Strategy + \"\\\"\")); err != nil {\n\t\treturn err\n\t}\n\tg.group = rs.RuleGroup\n\n\tvar native map[string]any\n\tif err := unmarshal(&native); err != nil {\n\t\treturn errors.Wrap(err, \"failed to unmarshal rulefmt.configRuleAdapter\")\n\t}\n\tdelete(native, \"partial_response_strategy\")\n\n\tg.nativeRuleGroup = native\n\treturn nil\n}\n\nfunc (g configRuleAdapter) MarshalYAML() (any, error) {\n\treturn struct {\n\t\tRuleGroup map[string]any `yaml:\",inline\"`\n\t}{\n\t\tRuleGroup: g.nativeRuleGroup,\n\t}, nil\n}\n\n// TODO(bwplotka): Replace this with upstream implementation after https://github.com/prometheus/prometheus/issues/7128 is fixed.\nfunc (g configRuleAdapter) validate() (errs []error) {\n\tset := map[string]struct{}{}","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/rules/manager.go#L215-L251","documentation":"configRuleAdapter.UnmarshalYAML first decodes into the embedded rulefmt.RuleGroup and then re-unmarshals the raw node into a native map to preserve unknown fields. If that second pass fails, the YAML could not be represented as rulefmt.configRuleAdapter.","triggerScenarios":"A rule file contains YAML that does not match the Prometheus rule group schema: wrong field types (e.g. interval: \"abc\"), a scalar where a map is expected, or malformed structure for RuleGroup.","commonSituations":"Hand-edited rules file with a type error; version change where a field was renamed; passing a non-rule-group YAML file to the rules manager.","solutions":["Validate the rules file with promtool check rules before applying","Fix the field type reported by the nested YAML error (see the wrapped cause)","Ensure 'interval', 'name', 'rules' fields follow the rulefmt.RuleGroup schema","Pin matching Prometheus/Thanos versions if a field was renamed"],"exampleFix":"// before\ninterval: 30s\nrules: \"not-a-list\"\n// after\ninterval: 30s\nrules:\n  - alert: HighErrorRate\n    expr: up == 0\n    for: 5m","handlingStrategy":"validation","validationCode":"// run before handing a file to the manager\ngroups, errs := rulefmt.ParseFile(file)\nif len(errs) > 0 {\n    return fmt.Errorf(\"invalid rule file %s: %v\", file, errs)\n}","typeGuard":null,"tryCatchPattern":"var cg configRuleAdapter\nif err := yaml.UnmarshalStrict(b, &cg); err != nil {\n    var yerr *yaml.TypeError\n    if errors.As(err, &yerr) {\n        // report field-level type errors to the user\n    }\n    return errors.Wrap(err, \"failed to unmarshal rulefmt.configRuleAdapter\")\n}","preventionTips":["Run promtool check rules in CI on every rule file change","Use yaml.UnmarshalStrict to surface typos in field names early","Keep Prometheus rulefmt schema versions in sync with the files you ship"],"tags":["yaml","unmarshal","config"],"backgroundTag":"yaml-parse-error","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"}