{"record":{"id":"4fa4cb3d2d424c1b","repo":"thanos-io/thanos","slug":"empty-targethealth","errorCode":null,"errorMessage":"empty targetHealth","messagePattern":"empty targetHealth","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/targets/targetspb/custom.go","lineNumber":39,"sourceCode":"\t}\n}\n\nfunc NewWarningTargetsResponse(warning error) *TargetsResponse {\n\treturn &TargetsResponse{\n\t\tResult: &TargetsResponse_Warning{\n\t\t\tWarning: warning.Error(),\n\t\t},\n\t}\n}\n\nfunc (x *TargetHealth) UnmarshalJSON(entry []byte) error {\n\tfieldStr, err := strconv.Unquote(string(entry))\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"targetHealth: unquote %v\", string(entry))\n\t}\n\n\tif fieldStr == \"\" {\n\t\treturn errors.New(\"empty targetHealth\")\n\t}\n\n\tstate, ok := TargetHealth_value[strings.ToUpper(fieldStr)]\n\tif !ok {\n\t\treturn errors.Errorf(\"unknown targetHealth: %v\", string(entry))\n\t}\n\t*x = TargetHealth(state)\n\treturn nil\n}\n\nfunc (x *TargetHealth) MarshalJSON() ([]byte, error) {\n\treturn []byte(strconv.Quote(strings.ToLower(x.String()))), nil\n}\n\nfunc (x TargetHealth) Compare(y TargetHealth) int {\n\treturn int(x) - int(y)\n}\n","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/targets/targetspb/custom.go#L21-L57","documentation":"After successfully unquoting, TargetHealth.UnmarshalJSON rejects an empty string value because health must be one of the defined enum states (unknown, healthy, unhealthy). An empty targetHealth field in JSON triggers this error.","triggerScenarios":"TargetHealth.UnmarshalJSON receives a JSON string that unquotes to \"\", e.g. \"health\": \"\" or \"health\": \"\\\"\\\"\" double-encoded.","commonSituations":"Empty DB/struct fields serialized to JSON by generic tooling; Prometheus targets data with missing health defaulted to empty string; hand-written fixtures.","solutions":["Provide a valid health value: \"unknown\", \"healthy\", or \"unhealthy\".","If the source data may be empty, set the field to \"unknown\" before unmarshaling.","Make the field a pointer (*TargetHealth) and skip unmarshal when absent instead of sending an empty string.","Fix double-encoded values like \"\\\"\\\"\" to plain \"unknown\"."],"exampleFix":"// before\n{\"health\": \"\"}\n// after\n{\"health\": \"unknown\"}","handlingStrategy":"validation","validationCode":"if health == \"\" { health = \"unknown\" }","typeGuard":"func validTargetHealth(s string) bool { return s == \"unknown\" || s == \"healthy\" || s == \"unhealthy\" }","tryCatchPattern":null,"preventionTips":["Default missing health to \"unknown\" before serialization","Make optional fields pointers so absence ≠ empty string","Validate JSON fixtures against a schema"],"tags":["json","validation","enum","thanos-targets"],"backgroundTag":"empty-required-field","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"}