{"id":"d717194b31f376eb","repo":"aio-libs/aiohttp","slug":"1007","errorCode":"1007","errorMessage":"Invalid UTF-8 text message","messagePattern":"Invalid UTF-8 text message","errorType":"exception","errorClass":"WebSocketError","httpStatus":null,"severity":"error","filePath":"aiohttp/_websocket/reader_c.py","lineNumber":272,"sourceCode":"                    ),\n                )\n                if self._max_msg_size and len(payload_merged) > self._max_msg_size:\n                    raise WebSocketError(\n                        WSCloseCode.MESSAGE_TOO_BIG,\n                        f\"Decompressed message exceeds size limit {self._max_msg_size}\",\n                    )\n            elif type(assembled_payload) is bytes:\n                payload_merged = assembled_payload\n            else:\n                payload_merged = bytes(assembled_payload)\n\n            size = len(payload_merged)\n            if opcode == OP_CODE_TEXT:\n                if self._decode_text:\n                    try:\n                        text = payload_merged.decode(\"utf-8\")\n                    except UnicodeDecodeError as exc:\n                        raise WebSocketError(\n                            WSCloseCode.INVALID_TEXT, \"Invalid UTF-8 text message\"\n                        ) from exc\n\n                    # XXX: The Text and Binary messages here can be a performance\n                    # bottleneck, so we use tuple.__new__ to improve performance.\n                    # This is not type safe, but many tests should fail in\n                    # test_client_ws_functional.py if this is wrong.\n                    msg = TUPLE_NEW(WSMessageText, (text, size, \"\", WS_MSG_TYPE_TEXT))\n                else:\n                    # Return raw bytes for TEXT messages when decode_text=False\n                    msg = TUPLE_NEW(\n                        WSMessageTextBytes, (payload_merged, size, \"\", WS_MSG_TYPE_TEXT)\n                    )\n            else:\n                msg = TUPLE_NEW(\n                    WSMessageBinary, (payload_merged, size, \"\", WS_MSG_TYPE_BINARY)\n                )\n","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/_websocket/reader_c.py#L254-L290","documentation":"WebSocketError (1007 INVALID_TEXT) raised in _handle_frame when a TEXT message payload fails to decode as UTF-8 (decode_text is True). RFC 6455 requires TEXT frames to be valid UTF-8; aiohttp validates this and rejects invalid payloads. Surfaced as msg.type == WSMsgType.ERROR with msg.data.code == 1007.","triggerScenarios":"A frame with opcode 0x1 (TEXT) whose assembled payload contains invalid UTF-8 byte sequences, decoded at reader_c.py:270. Triggered by a peer that sends binary data mislabelled as a TEXT frame, or a partial UTF-8 sequence split across fragments that was reassembled incorrectly by the sender.","commonSituations":"A peer encoding text in latin-1/GBK/Shift-JIS but sending as TEXT; binary data accidentally sent via send_str() on the peer; a fragmenting sender that splits a multi-byte UTF-8 character incorrectly; legacy/buggy clients.","solutions":["Ensure the sender only sends valid UTF-8 in TEXT frames; use BINARY frames (send_bytes) for non-text payloads.","If you can tolerate raw bytes, construct the server/client with decode_text=False so TEXT payloads are returned as bytes and 1007 is not raised for them.","Handle msg.type == WSMsgType.ERROR / code 1007 in the receive loop and close/reconnect.","On the sender, encode explicitly: payload.encode('utf-8') before framing."],"exampleFix":"# before\nws = WebSocketResponse(decode_text=True)  # invalid UTF-8 TEXT -> 1007\n\n# after (option A: accept raw bytes)\nws = WebSocketResponse(decode_text=False)\n# option B: peer must send BINARY for non-utf8 data: await ws.send_bytes(data)","handlingStrategy":"type-guard","validationCode":"# if non-UTF-8 TEXT is expected, receive raw bytes instead of decoding\nws = WebSocketResponse(decode_text=False)  # server side\n# ws = await session.ws_connect(url, decode_text=False)  # client side (if supported)","typeGuard":"from aiohttp import WSMsgType\n\ndef is_invalid_text(msg) -> bool:\n    return msg.type is WSMsgType.ERROR and getattr(msg.data, 'code', None) == 1007","tryCatchPattern":"msg = await ws.receive()\nif msg.type is aiohttp.WSMsgType.ERROR and msg.data.code == 1007:\n    log.warning('peer sent invalid UTF-8 TEXT frame')\n    await ws.close()","preventionTips":["Send non-text payloads as BINARY (send_bytes), never as TEXT.","If you must accept possibly-invalid text, construct the endpoint with decode_text=False.","Encode TEXT payloads explicitly with .encode('utf-8') on the sender."],"tags":["websocket","encoding","utf8","text","cython","close-1007"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}