{"record":{"id":"177be9342c2a4411","repo":"aio-libs/aiohttp","slug":"unsupported-body-type-r","errorCode":null,"errorMessage":"Unsupported body type %r","messagePattern":"Unsupported body type %r","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_response.py","lineNumber":620,"sourceCode":"\n        self._zlib_executor_size = zlib_executor_size\n        self._zlib_executor = zlib_executor\n\n    @property\n    def body(self) -> bytes | bytearray | Payload | None:\n        return self._body\n\n    @body.setter\n    def body(self, body: Any) -> None:\n        if body is None:\n            self._body = None\n        elif isinstance(body, (bytes, bytearray)):\n            self._body = body\n        else:\n            try:\n                self._body = body = payload.PAYLOAD_REGISTRY.get(body)\n            except payload.LookupError:\n                raise ValueError(\"Unsupported body type %r\" % type(body))\n\n            headers = self._headers\n\n            # set content-type\n            if hdrs.CONTENT_TYPE not in headers:\n                headers[hdrs.CONTENT_TYPE] = body.content_type\n\n            # copy payload headers\n            if body.headers:\n                for key, value in body.headers.items():\n                    if key not in headers:\n                        headers[key] = value\n\n        self._compressed_body = None\n\n    @property\n    def text(self) -> str | None:\n        if self._body is None:","sourceCodeStart":602,"sourceCodeEnd":638,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_response.py#L602-L638","documentation":"Raised by the Response.body setter when the value is not None, not bytes/bytearray, and not registered in aiohttp.payload.PAYLOAD_REGISTRY. The registry maps Python types (str, dict via JsonPayload, file objects via StreamReader, etc.) to Payload adapters; anything not registered is rejected as unsupported rather than silently coerced.","triggerScenarios":"Assigning `resp.body = 42`, a custom class instance, a `pathlib.Path`, a `memoryview` of an unsupported backing type, or any object whose type has no registered Payload adapter. Also triggered when a Payload subclass is registered but the value is a sibling type.","commonSituations":"Returning ORM model instances, dataclasses, or Pydantic objects directly as body without serializing. Passing a generator/async generator that isn't wrapped in a StreamingResponse-like payload. Forgetting that str needs to go through text= (str IS registered but the error fires for truly unknown types).","solutions":["Serialize to bytes first: `resp.body = json.dumps(obj).encode()` or `orjson.dumps(obj)`.","Use `text=` for str payloads, `body=` for bytes, `json_response()` for dict/list objects.","Register a custom Payload adapter via `aiohttp.payload.PAYLOAD_REGISTRY.register(MyType, MyPayload)` if you need first-class support.","Wrap file-like objects in `aiohttp.streamer` or use `web.FileResponse` for filesystem paths."],"exampleFix":"// before\nresp.body = my_dataclass_instance  # LookupError -> ValueError\n\n// after\nresp.body = json.dumps(asdict(my_dataclass_instance)).encode('utf-8')","handlingStrategy":"type-guard","validationCode":"def to_body_bytes(value):\n    if isinstance(value, (bytes, bytearray)):\n        return bytes(value)\n    if isinstance(value, str):\n        return value.encode('utf-8')\n    # fall back to JSON for dict/list/dataclass-like objects\n    return json.dumps(value).encode('utf-8')\n\nresp.body = to_body_bytes(value)","typeGuard":"import bytes as _\n\ndef is_supported_body(value) -> bool:\n    return value is None or isinstance(value, (bytes, bytearray, str, dict, list, tuple))","tryCatchPattern":"try:\n    resp.body = value\nexcept ValueError:\n    resp.body = json.dumps(value).encode('utf-8')","preventionTips":["Serialize ORM/dataclass/Pydantic objects to bytes before assigning body.","Use text= for str, body= for bytes, json_response() for objects.","Register custom Payload adapters via PAYLOAD_REGISTRY for first-class types.","Use web.FileResponse for filesystem paths."],"tags":["aiohttp","web-response","body","payload-registry","serialization"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}