{"id":"4ae9130b44164b9f","repo":"aio-libs/aiohttp","slug":"data-argument-must-be-byte-ish-r-4ae913","errorCode":null,"errorMessage":"data argument must be byte-ish (%r)","messagePattern":"data argument must be byte-ish \\(%r\\)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_ws.py","lineNumber":475,"sourceCode":"        \"\"\"Send a frame over the websocket.\"\"\"\n        if self._writer is None:\n            raise RuntimeError(\"Call .prepare() first\")\n        await self._writer.send_frame(message, opcode, compress)\n\n    async def send_str(self, data: str, compress: int | None = None) -> None:\n        if self._writer is None:\n            raise RuntimeError(\"Call .prepare() first\")\n        if not isinstance(data, str):\n            raise TypeError(\"data argument must be str (%r)\" % type(data))\n        await self._writer.send_frame(\n            data.encode(\"utf-8\"), WSMsgType.TEXT, compress=compress\n        )\n\n    async def send_bytes(self, data: bytes, compress: int | None = None) -> None:\n        if self._writer is None:\n            raise RuntimeError(\"Call .prepare() first\")\n        if not isinstance(data, (bytes, bytearray, memoryview)):\n            raise TypeError(\"data argument must be byte-ish (%r)\" % type(data))\n        await self._writer.send_frame(data, WSMsgType.BINARY, compress=compress)\n\n    async def send_json(\n        self,\n        data: Any,\n        compress: int | None = None,\n        *,\n        dumps: JSONEncoder = json.dumps,\n    ) -> None:\n        await self.send_str(dumps(data), compress=compress)\n\n    async def send_json_bytes(\n        self,\n        data: Any,\n        compress: int | None = None,\n        *,\n        dumps: JSONBytesEncoder,\n    ) -> None:","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/web_ws.py#L457-L493","documentation":"Raised by WebSocketResponse.send_bytes() as a TypeError when the `data` argument is not one of bytes, bytearray, or memoryview. send_bytes encodes and transmits a BINARY frame, which must be raw bytes; passing a str (or int/None/dict) has no valid binary representation. The offending type is included in the message via %r.","triggerScenarios":"Calling `await ws.send_bytes('text')` (passing a str), `ws.send_bytes(123)`, `ws.send_bytes(None)`, or any non-bytes value. The isinstance check at aiohttp/web_ws.py:474-475 fires after the prepare check.","commonSituations":"Mixing up send_str (for text) and send_bytes (for binary); passing a JSON string instead of using send_json; reading a file in text mode and forwarding the str; passing a serialised object that returns str from its encoder.","solutions":["Pass bytes: encode strings first, e.g. `await ws.send_bytes(value.encode('utf-8'))`.","Use send_str() when you actually have text, or send_json() for JSON payloads.","If using an encoder that returns bytes (e.g. orjson.dumps), use send_json_bytes() which routes to send_bytes correctly.","Add a type guard so callers with mixed types route to the correct method."],"exampleFix":"# before\nawait ws.send_bytes('hello')\n\n# after\nawait ws.send_bytes(b'hello')\n# or, for text:\nawait ws.send_str('hello')","handlingStrategy":"type-guard","validationCode":"from collections.abc import Buffer\n\ndef to_bytes(data) -> bytes:\n    if isinstance(data, (bytes, bytearray, memoryview)):\n        return bytes(data)\n    raise TypeError(f\"expected byte-ish, got {type(data)!r}\")\n\nawait ws.send_bytes(to_bytes(payload))","typeGuard":"def is_byteish(data) -> bool:\n    return isinstance(data, (bytes, bytearray, memoryview))","tryCatchPattern":"try:\n    await ws.send_bytes(data)\nexcept TypeError as e:\n    if \"byte-ish\" in str(e):\n        await ws.send_bytes(str(data).encode())\n    else:\n        raise","preventionTips":["Encode strings before passing to send_bytes, or use send_str for text.","Use send_json_bytes with a bytes-returning encoder for JSON.","Add a type hint and a quick isinstance check at API boundaries."],"tags":["websocket","server","types","send-bytes"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}