{"record":{"id":"6f4cb51d79762268","repo":"jaegertracing/jaeger","slug":"failed-marshalling-http-response-to-json-w","errorCode":null,"errorMessage":"failed marshalling HTTP response to JSON: %w","messagePattern":"failed marshalling HTTP response to JSON: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"cmd/jaeger/internal/extension/jaegerquery/internal/json_marshaler.go","lineNumber":40,"sourceCode":"\t\tmarshaler.Indent = prettyPrintIndent\n\t}\n\treturn func(w io.Writer, response any) error {\n\t\treturn marshaler.Marshal(w, response.(proto.Message))\n\t}\n}\n\n// newStructJSONMarshaler returns a marshaler that uses the built-in encoding/json package for marshaling basic structs to JSON.\nfunc newStructJSONMarshaler(prettyPrint bool) jsonMarshaler {\n\tmarshaler := json.Marshal\n\tif prettyPrint {\n\t\tmarshaler = func(v any) ([]byte, error) {\n\t\t\treturn json.MarshalIndent(v, \"\", prettyPrintIndent)\n\t\t}\n\t}\n\treturn func(w io.Writer, response any) error {\n\t\tresp, err := marshaler(response)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed marshalling HTTP response to JSON: %w\", err)\n\t\t}\n\t\t_, err = w.Write(resp)\n\t\treturn err\n\t}\n}\n","sourceCodeStart":22,"sourceCodeEnd":46,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/extension/jaegerquery/internal/json_marshaler.go#L22-L46","documentation":"The HTTP API's JSON marshaler closure marshals the response value first, then writes it; a marshal failure is wrapped as \"failed marshalling HTTP response to JSON\". It distinguishes encoding failures from write failures so operators know the response never made it onto the wire as valid JSON.","triggerScenarios":"A response value that cannot be serialized by encoding/json (e.g. an unsupported type such as chan or func, a NaN/Inf float, or a cyclic structure) reaches writeJSON on any query endpoint.","commonSituations":"A backend/storage plugin or custom query returns data containing values json.Marshal cannot handle; pretty-print mode using MarshalIndent hitting the same on large/odd payloads; version drift introducing a new field type.","solutions":["Read the wrapped cause to identify the offending field/type in the response struct.","Sanitize or convert unsupported values (NaN/Inf to 0 or strings, custom types to Marshaler) before returning them from the handler.","If caused by a plugin or forked code, fix that component's response types; otherwise file an issue with the endpoint and query that triggered it."],"exampleFix":"// before\ntype resp struct { Duration float64 }\n// after\ntype resp struct { Duration string } // e.g. \"1.5s\" instead of a float that may be NaN","handlingStrategy":"type-guard","validationCode":"if err := json.Marshal(response); err != nil {\n    return fmt.Errorf(\"response not JSON-serializable: %w\", err)\n}\n// run on handler output before returning it to writeJSON","typeGuard":"func jsonSafe(v any) bool {\n    _, err := json.Marshal(v)\n    return err == nil\n}","tryCatchPattern":"resp, err := client.Do(req)\n// server-side: a 500 with message 'failed marshalling HTTP response to JSON' means a handler returned unserializable data; check the wrapped cause for the offending type/field.","preventionTips":["Avoid NaN/Inf floats and chan/func fields in response structs.","Add unit tests that marshal every handler's response payload.","Sanitize values from plugins/storage before placing them in API responses."],"tags":["json","marshalling","http"],"backgroundTag":"json-marshal-failed","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}