{"record":{"id":"f8e5e9b2c650adbb","repo":"AlexxIT/go2rtc","slug":"failed-to-marshal-request-body-w","errorCode":null,"errorMessage":"failed to marshal request body: %w","messagePattern":"failed to marshal request body: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/ring/api.go","lineNumber":413,"sourceCode":"\tvar ticket SocketTicketResponse\n\tif err := json.Unmarshal(response, &ticket); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to unmarshal socket ticket response: %w\", err)\n\t}\n\n\treturn &ticket, nil\n}\n\nfunc (c *RingApi) Request(method, url string, body interface{}) ([]byte, error) {\n\t// Ensure we have a valid session\n\tif err := c.ensureSession(); err != nil {\n\t\treturn nil, fmt.Errorf(\"session validation failed: %w\", err)\n\t}\n\n\tvar bodyReader io.Reader\n\tif body != nil {\n\t\tjsonBody, err := json.Marshal(body)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to marshal request body: %w\", err)\n\t\t}\n\t\tbodyReader = bytes.NewReader(jsonBody)\n\t}\n\n\t// Create request\n\treq, err := http.NewRequest(method, url, bodyReader)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create request: %w\", err)\n\t}\n\n\t// Set headers\n\treq.Header.Set(\"Authorization\", \"Bearer \"+c.authToken.AccessToken)\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"Accept\", \"application/json\")\n\treq.Header.Set(\"hardware_id\", c.hardwareID)\n\treq.Header.Set(\"User-Agent\", \"android:com.ringapp\")\n\n\t// Make request with retries","sourceCodeStart":395,"sourceCodeEnd":431,"githubUrl":"https://github.com/AlexxIT/go2rtc/blob/c245815e75e2a5fd60b4290f12bfc04e55a984d3/pkg/ring/api.go#L395-L431","documentation":"RingApi.Request marshals the caller-supplied 'body' argument to JSON before sending. If json.Marshal fails on that value, the request is never sent and this error is returned. It indicates the request payload contains data that cannot be serialized to JSON (unsupported types, cycles, invalid values).","triggerScenarios":"Passing a body to Request containing unmarshalable values: channels, funcs, cyclic pointers, NaN/Inf floats, or a custom type with a MarshalJSON method that returns an error.","commonSituations":"Accidentally passing a Go struct with unexported/unsupported fields, embedding an io.Reader or func field, or passing non-serializable runtime values (e.g., a context or logger) as the body instead of the intended DTO.","solutions":["Inspect the body value: remove or replace fields that are not JSON-serializable (chan, func, cycles, NaN/Inf)","Add json tags to struct fields so the intended payload is marshaled correctly","Give unserializable types a MarshalJSON method, or pre-convert them to a serializable representation before calling Request","Pass bytes.NewBuffer/[]byte of pre-marshaled JSON if you must control encoding yourself"],"exampleFix":"// before\nc.Request(\"POST\", url, map[string]interface{}{\"callback\": someFunc}) // marshal fails\n// after\nc.Request(\"POST\", url, struct {\n    DeviceID string `json:\"device_id\"`\n}{DeviceID: id})","handlingStrategy":"validation","validationCode":"// Go: verify the body serializes before the call\nfunc assertSerializable(v interface{}) error {\n    _, err := json.Marshal(v)\n    return err // call before api.Request\n}","typeGuard":null,"tryCatchPattern":"// Go\nif err := assertSerializable(body); err != nil {\n    return fmt.Errorf(\"bad request payload: %w\", err)\n}\nresp, err := api.Request(method, url, body)\nif err != nil && strings.Contains(err.Error(), \"failed to marshal request body\") {\n    return fmt.Errorf(\"request body not JSON-serializable: %w\", err)\n}","preventionTips":["Use dedicated request DTO structs with json tags instead of ad-hoc map[string]interface{}","Never put chan, func, or context values in a request payload","Test each request type's marshaling in unit tests","Keep float values finite (no NaN/Inf) in payloads"],"tags":["json","serialization","request-body"],"backgroundTag":"json-marshal-failed","analyzedSha":"c245815e75e2a5fd60b4290f12bfc04e55a984d3","analyzedAt":"2026-09-07T11:47:02.965Z","contentChangedAt":"2026-09-07T11:47:02.965Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}