aio-libs/aiohttp · error · WSMessageTypeError
Received message {msg.type}:{msg.data!r} is not WSMsgType.BI
Error message
Received message {msg.type}:{msg.data!r} is not WSMsgType.BINARY What it means
Raised by WebSocketResponse.receive_bytes() as a WSMessageTypeError (a TypeError subclass) when the received message is not a BINARY frame. receive_bytes() calls receive() then asserts msg.type is WSMsgType.BINARY; a TEXT frame or a control/close message fails the check. The actual type and data are included in the message.
Source
Thrown at aiohttp/web_ws.py:701
self: "WebSocketResponse[_DecodeText]", *, timeout: float | None = None
) -> str | bytes: ...
async def receive_str(self, *, timeout: float | None = None) -> str | bytes:
"""Receive TEXT message.
Returns str when decode_text=True (default), bytes when decode_text=False.
"""
msg = await self.receive(timeout)
if msg.type is not WSMsgType.TEXT:
raise WSMessageTypeError(
f"Received message {msg.type}:{msg.data!r} is not WSMsgType.TEXT"
)
return msg.data
async def receive_bytes(self, *, timeout: float | None = None) -> bytes:
msg = await self.receive(timeout)
if msg.type is not WSMsgType.BINARY:
raise WSMessageTypeError(
f"Received message {msg.type}:{msg.data!r} is not WSMsgType.BINARY"
)
return msg.data
@overload
async def receive_json(
self: "WebSocketResponse[Literal[True]]",
*,
loads: JSONDecoder = ...,
timeout: float | None = None,
) -> Any: ...
@overload
async def receive_json(
self: "WebSocketResponse[Literal[False]]",
*,
loads: Callable[[bytes], Any] = ...,
timeout: float | None = None,View on GitHub (pinned to c0ef574e29)
Solutions
- Use the generic receive() and branch on msg.type to handle TEXT and control frames.
- Verify `msg.type == WSMsgType.BINARY` before interpreting data as bytes.
- Catch WSMessageTypeError (from aiohttp.client_exceptions) to recover gracefully.
- Agree on a single frame-type convention with the peer.
Example fix
# before
async for _ in ws:
data = await ws.receive_bytes() # raises on TEXT/CLOSE
# after
async for msg in ws:
if msg.type == WSMsgType.BINARY:
handle_binary(msg.data)
elif msg.type == WSMsgType.TEXT:
handle_text(msg.data) Defensive patterns
Strategy: try-catch
Validate before calling
from aiohttp import WSMsgType
async def receive_binary(ws):
msg = await ws.receive()
if msg.type is WSMsgType.BINARY:
return msg.data
return None Type guard
from aiohttp import WSMsgType
def is_binary(msg) -> bool:
return msg.type is WSMsgType.BINARY Try / catch
from aiohttp.client_exceptions import WSMessageTypeError
try:
data = await ws.receive_bytes()
except WSMessageTypeError:
msg = await ws.receive() # handle non-binary frame Prevention
- Branch on msg.type from generic receive() for mixed protocols.
- Catch WSMessageTypeError to recover from unexpected frame types.
- Confirm the peer's frame convention before assuming binary.
When it happens
Trigger: Calling `await ws.receive_bytes()` when the peer sent a TEXT frame, or when receive() returned a CLOSE/CLOSING/CLOSED/PING/PONG control message. The check at aiohttp/web_ws.py:700-703 raises.
Common situations: Peer sends text but the server assumes binary; a client sending JSON text when the server expected msgpack/protobuf binary; receive_bytes() called after the connection began closing so receive() returns a CLOSE sentinel.
Related errors
- Received message {msg.type}:{msg.data!r} is not WSMsgType.TE
- data argument must be byte-ish (%r)
- Concurrent call to receive() is not allowed
- WebSocket connection is closed.
- Compress wbits must between 9 and 15, zlib does not support
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/4a4a83ac04722223.json.
Report an issue: GitHub.