From 0bc4f55e1ae29a9e3df17d972b65fe804609da6e Mon Sep 17 00:00:00 2001 From: Alexander Payne Date: Sat, 28 Feb 2026 20:03:15 -0500 Subject: [PATCH] fix: resolve WebSocket crashes from websockets 16.0 incompatibility The /ws redirect handler crashed with AttributeError because websockets 16.0 removed the legacy transfer_data_task attribute. The /swarm/live endpoint could also error on early client disconnects during accept. Co-Authored-By: Claude Opus 4.6 --- src/dashboard/app.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dashboard/app.py b/src/dashboard/app.py index a705c18..cc2d3de 100644 --- a/src/dashboard/app.py +++ b/src/dashboard/app.py @@ -410,11 +410,17 @@ app.include_router(cascade_router) @app.websocket("/ws") async def ws_redirect(websocket: WebSocket): - """Catch stale /ws connections and close cleanly.""" + """Catch stale /ws connections and close cleanly. + + websockets 16.0 dropped the legacy ``transfer_data_task`` attribute, + so calling ``websocket.close()`` after accept triggers an + AttributeError. Use the raw ASGI send instead. + """ await websocket.accept() try: await websocket.close(code=1008, reason="Deprecated endpoint") except AttributeError: + # websockets >= 16.0 — close via raw ASGI message await websocket.send({"type": "websocket.close", "code": 1008})