{"record":{"id":"37a5524b61ad5f68","repo":"thanos-io/thanos","slug":"error-marshaling-response","errorCode":null,"errorMessage":"error marshaling response","messagePattern":"error marshaling response","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"pkg/api/api.go","lineNumber":287,"sourceCode":"\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tif shouldNotCacheBecauseOfWarnings(warnings) {\n\t\tw.Header().Set(\"Cache-Control\", \"no-store\")\n\t}\n\tw.WriteHeader(http.StatusOK)\n\n\tresp := &response{\n\t\tStatus: StatusSuccess,\n\t\tData:   data,\n\t}\n\tfor _, warn := range warnings {\n\t\tresp.Warnings = append(resp.Warnings, warn.Error())\n\t}\n\n\tjson := jsoniter.ConfigCompatibleWithStandardLibrary\n\tb, err := json.Marshal(resp)\n\tif err != nil {\n\t\tlevel.Error(logger).Log(\"msg\", \"error marshaling response\", \"err\", err)\n\t\thttp.Error(w, err.Error(), http.StatusInternalServerError)\n\t\treturn\n\t}\n\n\tif n, err := w.Write(b); err != nil {\n\t\tlevel.Error(logger).Log(\"msg\", \"error writing response\", \"bytesWritten\", n, \"err\", err)\n\t}\n}\n\nfunc RespondError(w http.ResponseWriter, apiErr *ApiError, data any, logger log.Logger) {\n\tw.Header().Set(\"Content-Type\", \"application/json\")\n\tw.Header().Set(\"Cache-Control\", \"no-store\")\n\n\tvar code int\n\tswitch apiErr.Typ {\n\tcase ErrorBadData:\n\t\tcode = http.StatusBadRequest\n\tcase ErrorExec:\n\t\tcode = 422","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/api/api.go#L269-L305","documentation":"API.Respond marshals the response struct with jsoniter (stdlib-compatible). If marshaling fails, it logs 'error marshaling response' and returns HTTP 500 with the marshal error text. This is an internal encoding failure, not a client input problem.","triggerScenarios":"json.Marshal(resp) returns an error — e.g. resp.Data contains a value JSON cannot encode (NaN/Inf floats from query results, a channel/func field, or a custom MarshalJSON returning an error).","commonSituations":"Query endpoints returning NaN/Inf values in series data; a handler returning unencodable types (e.g. unmarshalable time formats or cyclic structures) in a custom API extension.","solutions":["Check the logged err field to find which field fails to marshal.","Sanitize numeric results: replace NaN/Inf with null before responding.","Fix the handler's return type so it contains only JSON-encodable values."],"exampleFix":"// before\nreturn promql.Vector{{Point: promql.Point{T: ts, V: math.NaN()}}}, nil\n// after\nv := math.NaN()\nif math.IsNaN(v) { v = 0 } // or encode as null\nreturn promql.Vector{{Point: promql.Point{T: ts, V: v}}}, nil","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp = sanitizeForJSON(resp) // replace NaN/Inf with nil\nb, err := json.Marshal(resp)\nif err != nil {\n    level.Error(logger).Log(\"msg\", \"error marshaling response\", \"err\", err)\n    http.Error(w, err.Error(), http.StatusInternalServerError)\n    return\n}","preventionTips":["Never return NaN/Inf floats in API handler results","Keep handler return types JSON-encodable (no funcs, channels, cyclic refs)","Add a test that marshals every endpoint's response shape"],"tags":["http","json","api"],"backgroundTag":"json-marshal-failed","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"}