{"record":{"id":"ab4236ef6f4a84fb","repo":"aio-libs/aiohttp","slug":"data-argument-must-be-byte-ish-r","errorCode":null,"errorMessage":"data argument must be byte-ish (%r)","messagePattern":"data argument must be byte-ish \\(%r\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"aiohttp/client_ws.py","lineNumber":294,"sourceCode":"    async def pong(self, message: bytes = b\"\") -> None:\n        await self._writer.send_frame(message, WSMsgType.PONG)\n\n    async def send_frame(\n        self, message: bytes, opcode: WSMsgType, compress: int | None = None\n    ) -> None:\n        \"\"\"Send a frame over the websocket.\"\"\"\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 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 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 = DEFAULT_JSON_ENCODER,\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":276,"sourceCodeEnd":312,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/client_ws.py#L276-L312","documentation":"Raised by ClientWebSocketResponse.send_bytes() when the data argument is not one of bytes, bytearray, or memoryview. The method exists specifically to transmit BINARY frames, so aiohttp refuses to guess how to encode non-byte payloads and fails fast rather than silently sending malformed data. The %r placeholder interpolates the actual type, making the call-site mistake obvious.","triggerScenarios":"Calling await ws.send_bytes('text') with a str; passing an int, float, dict, list, or None; passing a json.dumps(...) result (which is str) instead of json.dumps(...).encode(); calling send_bytes on data read from a text-mode file without encoding.","commonSituations":"Mixing up send_str and send_bytes; using send_bytes when the producer is a JSON/text serializer that returns str; reading from an open() opened without 'b'; passing a numpy array or other buffer-like object that is not one of the three accepted types.","solutions":["Pass bytes: encode text first with data.encode('utf-8') or use a bytes literal b'...'.","If the payload is text or JSON, use send_str / send_json instead of send_bytes.","Wrap non-byte buffers with bytes(obj) or memoryview(obj) before calling send_bytes.","Add a type check at the producer boundary so wrong types are caught before reaching the websocket."],"exampleFix":"# before\nawait ws.send_bytes(json.dumps(payload))\n# after\nawait ws.send_bytes(json.dumps(payload).encode('utf-8'))","handlingStrategy":"type-guard","validationCode":"def to_binary_frame(data) -> bytes:\n    if isinstance(data, (bytes, bytearray, memoryview)):\n        return bytes(data)\n    if isinstance(data, str):\n        return data.encode('utf-8')\n    raise TypeError(f'cannot send {type(data)} as a binary frame')\n\nawait ws.send_bytes(to_binary_frame(payload))","typeGuard":"from collections.abc import Buffer\nfrom typing import Any\n\ndef is_byte_ish(data: Any) -> bool:\n    return isinstance(data, (bytes, bytearray, memoryview))","tryCatchPattern":"try:\n    await ws.send_bytes(payload)\nexcept TypeError as exc:\n    if 'byte-ish' in str(exc):\n        payload = payload.encode('utf-8') if isinstance(payload, str) else bytes(payload)\n        await ws.send_bytes(payload)\n    else:\n        raise","preventionTips":["Pick send_str for text and send_bytes for binary - do not mix them.","Encode at the producer boundary so the websocket layer always sees bytes.","Unit-test the producer with both str and bytes inputs to catch type drift."],"tags":["websocket","client","type-error","send-bytes"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}