{"record":{"id":"21533145d34fbe17","repo":"psf/requests","slug":"ve","errorCode":null,"errorMessage":"{ve}","messagePattern":"\\{ve\\}","errorType":"exception","errorClass":"InvalidJSONError","httpStatus":null,"severity":"error","filePath":"src/requests/models.py","lineNumber":596,"sourceCode":"    ) -> None:\n        \"\"\"Prepares the given HTTP body data.\"\"\"\n\n        # Check if file, fo, generator, iterator.\n        # If not, run through normal process.\n\n        # Nottin' on you.\n        body = None\n        content_type = None\n\n        if not data and json is not None:\n            # urllib3 requires a bytes-like body. Python 2's json.dumps\n            # provides this natively, but Python 3 gives a Unicode string.\n            content_type = \"application/json\"\n\n            try:\n                body = complexjson.dumps(json, allow_nan=False)\n            except ValueError as ve:\n                raise InvalidJSONError(ve, request=self)\n\n            if not isinstance(body, bytes):\n                body = body.encode(\"utf-8\")\n\n        # data that proxies attributes to underlying objects needs hasattr\n        is_iterable = isinstance(data, Iterable) or hasattr(data, \"__iter__\")\n        if is_iterable and not isinstance(data, (str, bytes, list, tuple, Mapping)):\n            try:\n                length = super_len(data)\n            except (TypeError, AttributeError, UnsupportedOperation):\n                length = None\n\n            body = data\n\n            if getattr(body, \"tell\", None) is not None:\n                # Record the current file position before reading.\n                # This will allow us to rewind a file in the event\n                # of a redirect.","sourceCodeStart":578,"sourceCodeEnd":614,"githubUrl":"https://github.com/psf/requests/blob/8068356288978c4f54661ae6f95afe0e0831885e/src/requests/models.py#L578-L614","documentation":"Raised by PreparedRequest.prepare_body when json.dumps fails on the supplied json= argument. The default dumps is called with allow_nan=False, so NaN/Infinity (which are invalid per strict JSON) always trigger this; any other ValueError from the encoder (circular references via a custom encoder, non-serializable types) is also wrapped as InvalidJSONError. This signals that the request body could not be produced.","triggerScenarios":"Passing json=float('nan') or json=float('inf') (rejected by allow_nan=False); passing a non-serializable object (datetime, set, custom class) without a default= hook; circular references in nested structures.","commonSituations":"Logging/metrics payloads containing NaN from numeric processing; ORM objects or dataclasses not registered with a JSON encoder; third-party objects that look dict-like but aren't serializable.","solutions":["Sanitize NaN/Inf values before passing json= (replace with None or a string), or post-process with a custom serializer.","For non-serializable types, convert to plain dicts/lists first, or use a json= argument that is already a str produced by your own dumps with a default hook.","Catch InvalidJSONError and either serialize manually or fail the request gracefully."],"exampleFix":"// before\nimport math\npayload = {'ratio': float('nan')}\nrequests.post(url, json=payload)\n\n// after\nimport math\npayload = {'ratio': None if math.isnan(r) else r for r in [...]}\nrequests.post(url, json=payload)","handlingStrategy":"validation","validationCode":"import json, math, requests\n\ndef json_safe(obj):\n    if isinstance(obj, float) and (math.isnan(obj) or math.isinf(obj)):\n        return None\n    if isinstance(obj, dict):\n        return {k: json_safe(v) for k, v in obj.items()}\n    if isinstance(obj, (list, tuple)):\n        return [json_safe(v) for v in obj]\n    return obj","typeGuard":"import math\n\ndef is_json_safe(obj) -> bool:\n    if isinstance(obj, float):\n        return not (math.isnan(obj) or math.isinf(obj))\n    if isinstance(obj, dict):\n        return all(is_json_safe(v) for v in obj.values())\n    if isinstance(obj, (list, tuple)):\n        return all(is_json_safe(v) for v in obj)\n    return obj is None or isinstance(obj, (str, int, bool))","tryCatchPattern":"from requests.exceptions import InvalidJSONError\n\ntry:\n    resp = requests.post(url, json=payload)\nexcept InvalidJSONError:\n    # sanitize and retry, or serialize manually\n    resp = requests.post(url, data=json.dumps(payload, default=str))","preventionTips":["Sanitize NaN/Inf in numeric payloads before passing json=.","Convert non-serializable objects (datetime, set, custom) to primitives first.","Register a default= hook if you must serialize complex types."],"tags":["json","invalidjson","serialization","nan","http"],"backgroundTag":null,"analyzedSha":"8068356288978c4f54661ae6f95afe0e0831885e","analyzedAt":"2026-08-11T20:11:09.238Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}