{"record":{"id":"58c61ec4847764c2","repo":"aio-libs/aiohttp","slug":"connection-lost-58c61e","errorCode":null,"errorMessage":"Connection lost","messagePattern":"Connection lost","errorType":"exception","errorClass":"ConnectionResetError","httpStatus":null,"severity":"warning","filePath":"aiohttp/web_ws.py","lineNumber":365,"sourceCode":"        return (\n            response_headers,\n            protocol,\n            compress,\n            notakeover,\n        )\n\n    def _pre_start(self, request: BaseRequest) -> tuple[str | None, WebSocketWriter]:\n        self._loop = request._loop\n\n        headers, protocol, compress, notakeover = self._handshake(request)\n\n        self.set_status(101)\n        self.headers.update(headers)\n        self.force_close()\n        self._compress = compress\n        transport = request._protocol.transport\n        if transport is None:\n            raise ConnectionResetError(\"Connection lost\")\n        writer = WebSocketWriter(\n            request._protocol,\n            transport,\n            compress=compress,\n            notakeover=notakeover,\n            limit=self._writer_limit,\n        )\n\n        return protocol, writer\n\n    def _post_start(\n        self, request: BaseRequest, protocol: str | None, writer: WebSocketWriter\n    ) -> None:\n        self._ws_protocol = protocol\n        self._writer = writer\n\n        self._reset_heartbeat()\n","sourceCodeStart":347,"sourceCodeEnd":383,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_ws.py#L347-L383","documentation":"In _pre_start(), after the handshake succeeds, aiohttp fetches request._protocol.transport to build the WebSocketWriter. If the transport is already None (the underlying connection was closed/reset between the request arriving and prepare() running), it raises ConnectionResetError('Connection lost'). This is a network-level condition, not a programmer error — the client disconnected mid-handshake.","triggerScenarios":"Client closes the TCP connection immediately after sending the upgrade request (double-click, abrupt close); a network device reset the connection; the connection timed out at the OS level just as the handler started; high-latency/flaky mobile clients.","commonSituations":"Flaky mobile networks; load balancer health checks that open then immediately close; clients with very short timeouts; misbehaving browser tabs closed right after connecting; abuse from scanners opening sockets and dropping them.","solutions":["Wrap await ws.prepare(request) in try/except ConnectionResetError and treat it as a closed connection (return early, log at debug).","Don't treat this as a 5xx — the client is gone, so there is nobody to send an error response to.","Tune keepalive/timeout settings if this floods logs; consider connection-count limits."],"exampleFix":"// before\nws = web.WebSocketResponse()\nawait ws.prepare(request)\nasync for msg in ws: ...\n// after\nws = web.WebSocketResponse()\ntry:\n    await ws.prepare(request)\nexcept ConnectionResetError:\n    return ws  # client gone; nothing to send\nasync for msg in ws: ...","handlingStrategy":"try-catch","validationCode":"def connection_still_alive(request) -> bool:\n    return getattr(request._protocol, 'transport', None) is not None","typeGuard":"def transport_present(request) -> bool:\n    return request._protocol.transport is not None","tryCatchPattern":"ws = web.WebSocketResponse()\ntry:\n    await ws.prepare(request)\nexcept ConnectionResetError:\n    log.debug('client disconnected during WS handshake')\n    return ws  # nothing to send; client is gone","preventionTips":["Wrap ws.prepare() in try/except ConnectionResetError on flaky networks.","Don't log ConnectionResetError at error level — it's expected client churn.","Consider connection-count limits to bound the impact of churn."],"tags":["websocket","connection-reset","network","lifecycle"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}