aio-libs/aiohttp · error · TypeError
data argument must be byte-ish (%r)
Error message
data argument must be byte-ish (%r)
What it means
Raised as TypeError in ClientWebSocketResponse.send_bytes() when data is not a bytes-like object. Binary frames require raw bytes; the accepted types are bytes, bytearray, and memoryview.
Source
Thrown at aiohttp/client_ws.py:294
async def pong(self, message: bytes = b"") -> None:
await self._writer.send_frame(message, WSMsgType.PONG)
async def send_frame(
self, message: bytes, opcode: WSMsgType, compress: int | None = None
) -> None:
"""Send a frame over the websocket."""
await self._writer.send_frame(message, opcode, compress)
async def send_str(self, data: str, compress: int | None = None) -> None:
if not isinstance(data, str):
raise TypeError("data argument must be str (%r)" % type(data))
await self._writer.send_frame(
data.encode("utf-8"), WSMsgType.TEXT, compress=compress
)
async def send_bytes(self, data: bytes, compress: int | None = None) -> None:
if not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError("data argument must be byte-ish (%r)" % type(data))
await self._writer.send_frame(data, WSMsgType.BINARY, compress=compress)
async def send_json(
self,
data: Any,
compress: int | None = None,
*,
dumps: JSONEncoder = DEFAULT_JSON_ENCODER,
) -> None:
await self.send_str(dumps(data), compress=compress)
async def send_json_bytes(
self,
data: Any,
compress: int | None = None,
*,
dumps: JSONBytesEncoder,
) -> None:View on GitHub (pinned to c0ef574e29)
Solutions
- Pass bytes/bytearray/memoryview to send_bytes.
- Encode str first: data.encode('utf-8') or just use send_str.
- Convert buffer protocol objects: bytes(arr) or memoryview(arr).
- For JSON use send_json_bytes with an orjson-style encoder.
Example fix
# before
await ws.send_bytes('hello') # str
await ws.send_bytes([1,2,3]) # list
# after
await ws.send_bytes(b'hello')
await ws.send_bytes(bytes([1,2,3]))
# or for text
await ws.send_str('hello') Defensive patterns
Strategy: type-guard
Validate before calling
if not isinstance(data, (bytes, bytearray, memoryview)):
raise TypeError(f'send_bytes requires bytes-like, got {type(data).__name__}')
await ws.send_bytes(data) Type guard
def is_ws_binary(data) -> bool:
return isinstance(data, (bytes, bytearray, memoryview)) Prevention
- Convert buffer-protocol objects (numpy arrays, array.array) to bytes first.
- Encode str via send_str rather than passing encoded bytes to send_bytes unless you want a binary frame.
- Annotate helper functions with the bytes-like type to catch errors at typecheck time.
When it happens
Trigger: Fires at line 293-294 when isinstance(data, (bytes, bytearray, memoryview)) is False. Triggered by passing a str ('hello'), an int, a list of ints, or None to send_bytes.
Common situations: Passing a str to send_bytes (use send_str instead); passing JSON as a string instead of bytes; passing a numpy array or other buffer-like object without conversion.
Related errors
- data argument must be str (%r)
- Compress wbits must between 9 and 15, zlib does not support
- Concurrent call to receive() is not allowed
- filename must be an instance of str. Got: %s
- content_type must be an instance of str. Got: %s
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/ab4236ef6f4a84fb.json.
Report an issue: GitHub.