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})