{"id":"a6e2d66a0a2f299f","repo":"aio-libs/aiohttp","slug":"unable-to-read-body-part-as-bytes-use-write-to","errorCode":null,"errorMessage":"Unable to read body part as bytes. Use write() to consume.","messagePattern":"Unable to read body part as bytes\\. Use write\\(\\) to consume\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/multipart.py","lineNumber":662,"sourceCode":"            params[\"name\"] = value.name\n        if value.filename is not None:\n            params[\"filename\"] = value.filename\n\n        if params:\n            self.set_content_disposition(\"attachment\", True, **params)\n\n    def decode(self, encoding: str = \"utf-8\", errors: str = \"strict\") -> str:\n        raise TypeError(\"Unable to decode.\")\n\n    async def as_bytes(self, encoding: str = \"utf-8\", errors: str = \"strict\") -> bytes:\n        \"\"\"Raises TypeError as body parts should be consumed via write().\n\n        This is intentional: BodyPartReader payloads are designed for streaming\n        large data (potentially gigabytes) and must be consumed only once via\n        the write() method to avoid memory exhaustion. They cannot be buffered\n        in memory for reuse.\n        \"\"\"\n        raise TypeError(\"Unable to read body part as bytes. Use write() to consume.\")\n\n    async def write(self, writer: AbstractStreamWriter) -> None:\n        field = self._value\n        while chunk := await field.read_chunk(size=DEFAULT_CHUNK_SIZE):\n            async for d in field.decode_iter(chunk):\n                await writer.write(d)\n\n\nclass MultipartReader:\n    \"\"\"Multipart body reader.\"\"\"\n\n    #: Response wrapper, used when multipart readers constructs from response.\n    response_wrapper_cls = MultipartResponseWrapper\n    #: Multipart reader class, used to handle multipart/* body parts.\n    #: None points to type(self)\n    multipart_reader_cls: type[\"MultipartReader\"] | None = None\n    #: Body part reader class for non multipart/* content types.\n    part_reader_cls = BodyPartReader","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/multipart.py#L644-L680","documentation":"Raised unconditionally by BodyPartReaderPayload.as_bytes(). Like decode(), this method is intentionally forbidden because buffering a streaming body part (which can be gigabytes) into a single bytes object would risk memory exhaustion and can only succeed once. The payload is designed to be consumed via write().","triggerScenarios":"Calling `await payload.as_bytes()` on a BodyPartReaderPayload — e.g. generic code that awaits as_bytes() to inspect/serialize any payload. The method always raises TypeError for this payload type.","commonSituations":"Logging/inspection middleware that calls as_bytes() on all payloads; request forwarding code that buffers bodies; snapshotting payloads for retry/caching.","solutions":["Stream the payload through write() to a destination rather than buffering it.","If you truly need the bytes in memory, read the underlying BodyPartReader directly: `data = await reader.read()` before wrapping it.","Guard with isinstance(payload, BodyPartReaderPayload) and skip as_bytes() in generic pipelines."],"exampleFix":"// before\nbody = await payload.as_bytes()\n// after\nbuf = io.BytesIO()\nawait payload.write(BufferedWriter(buf))\nbody = buf.getvalue()\n","handlingStrategy":"type-guard","validationCode":"from aiohttp.multipart import BodyPartReaderPayload\nif isinstance(payload, BodyPartReaderPayload):\n    # cannot buffer — stream it instead\n    raise TypeError('stream this payload via write()')","typeGuard":"from aiohttp.multipart import BodyPartReaderPayload\n\ndef can_buffer(p) -> bool:\n    return not isinstance(p, BodyPartReaderPayload)","tryCatchPattern":"try:\n    body = await payload.as_bytes()\nexcept TypeError:\n    buf = io.BytesIO()\n    await payload.write(BufferedWriter(buf))\n    body = buf.getvalue()","preventionTips":["Check isinstance(payload, BodyPartReaderPayload) before as_bytes().","Design pipelines around streaming write() rather than buffering.","If bytes are mandatory, read the BodyPartReader before wrapping it."],"tags":["multipart","payload","streaming","memory","api-misuse"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}