{"record":{"id":"21ac3ee831c331ce","repo":"thanos-io/thanos","slug":"rule-unknown-type-field-provided-s-v","errorCode":null,"errorMessage":"rule: unknown type field provided %s; %v","messagePattern":"rule: unknown type field provided (.+?); (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/rules/rulespb/custom.go","lineNumber":234,"sourceCode":"\tswitch strings.ToLower(decider.Type) {\n\tcase \"recording\":\n\t\tr := &RecordingRule{}\n\t\tif err := json.Unmarshal(entry, r); err != nil {\n\t\t\treturn errors.Wrapf(err, \"rule: recording rule unmarshal: %v\", string(entry))\n\t\t}\n\n\t\tm.Result = &Rule_Recording{Recording: r}\n\tcase \"alerting\":\n\t\tr := &Alert{}\n\t\tif err := json.Unmarshal(entry, r); err != nil {\n\t\t\treturn errors.Wrapf(err, \"rule: alerting rule unmarshal: %v\", string(entry))\n\t\t}\n\n\t\tm.Result = &Rule_Alert{Alert: r}\n\tcase \"\":\n\t\treturn errors.Errorf(\"rule: no type field provided: %v\", string(entry))\n\tdefault:\n\t\treturn errors.Errorf(\"rule: unknown type field provided %s; %v\", decider.Type, string(entry))\n\t}\n\treturn nil\n}\n\nfunc (m *Rule) MarshalJSON() ([]byte, error) {\n\tif r := m.GetRecording(); r != nil {\n\t\treturn json.Marshal(struct {\n\t\t\t*RecordingRule\n\t\t\tType string `json:\"type\"`\n\t\t}{\n\t\t\tRecordingRule: r,\n\t\t\tType:          RuleRecordingType,\n\t\t})\n\t}\n\ta := m.GetAlert()\n\tif a.Alerts == nil {\n\t\t// Ensure that empty slices are marshaled as '[]' and not 'null'.\n\t\ta.Alerts = make([]*AlertInstance, 0)","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/rules/rulespb/custom.go#L216-L252","documentation":"Rule.UnmarshalJSON only accepts type values \"recording\" and \"alerting\" (case-insensitive). Any other non-empty value hits the default branch and errors with 'rule: unknown type field provided' including the given type and raw entry.","triggerScenarios":"Decoding rule entries with a typo'd or unsupported type such as \"alert\", \"record\", \"RecordingRule\", or a type from a different tool's schema.","commonSituations":"Typos in hand-written rules; mixing rule schemas from other systems (Grafana, Mimir variants) into Cortex rules files; tooling writing its own type names.","solutions":["Correct the type field to \"recording\" or \"alerting\"","Validate rules files against the expected schema before upload","Check whether the producing tool uses a different rule schema and convert accordingly"],"exampleFix":"// before\n{\"type\": \"alert\", \"name\": \"HighErrors\"}\n// after\n{\"type\": \"alerting\", \"name\": \"HighErrors\"}","handlingStrategy":"validation","validationCode":"allowed := map[string]bool{\"recording\": true, \"alerting\": true}\nvar d struct { Type string `json:\"type\"` }\nif json.Unmarshal(entry, &d) == nil && !allowed[strings.ToLower(d.Type)] {\n    return fmt.Errorf(\"unsupported rule type %q\", d.Type)\n}","typeGuard":"func hasKnownRuleType(entry []byte) bool {\n    var d struct { Type string `json:\"type\"` }\n    if json.Unmarshal(entry, &d) != nil { return false }\n    t := strings.ToLower(d.Type)\n    return t == \"recording\" || t == \"alerting\"\n}","tryCatchPattern":null,"preventionTips":["Use only \"recording\" and \"alerting\" as type values","Lint rules files for type typos before upload","Convert foreign rule schemas explicitly before ingesting into Cortex"],"tags":["json","schema","enum"],"backgroundTag":"invalid-enum-value","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"}