From 00180f8f7d827fa4c9aad640427d61be38c42ed8 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Mon, 27 Jul 2026 01:23:07 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20WebSocket=20403=20=E2=80=94=20register?= =?UTF-8?q?=20WebSocket=20routes=20without=20require=5Factive=5Fplugin=20d?= =?UTF-8?q?ependency?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WebSocket routes were getting require_active_plugin dependency applied via include_router(dependencies=[...]) which caused 403 Forbidden before the WebSocket upgrade could happen. Fix: Split router into HTTP routes (with dependency) and WebSocket routes (registered separately without the active-plugin check). WebSocket auth is handled inside the endpoint itself via session cookie verification. --- app/main.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/app/main.py b/app/main.py index c42835e..7e519a4 100644 --- a/app/main.py +++ b/app/main.py @@ -438,16 +438,28 @@ def create_app() -> FastAPI: # Wrap each HTTP route handler with plugin error isolation # Skip WebSocket routes — the wrapper breaks WS parameter # resolution and returns JSONResponse instead of WS close. + from starlette.routing import WebSocketRoute + http_routes = [] + ws_routes = [] for route in router.routes: if isinstance(route, WebSocketRoute): - continue - if hasattr(route, 'endpoint'): - route.endpoint = wrap_plugin_route(route.endpoint) - # Add active-plugin check as a router-level dependency + ws_routes.append(route) + else: + if hasattr(route, 'endpoint'): + route.endpoint = wrap_plugin_route(route.endpoint) + http_routes.append(route) + # Register HTTP routes with active-plugin check + router.routes = http_routes app.include_router( router, dependencies=[Depends(require_active_plugin(plugin_name))], ) + # Register WebSocket routes WITHOUT active-plugin check + # (WebSocket auth is handled inside the endpoint itself) + if ws_routes: + ws_router = APIRouter() + ws_router.routes = ws_routes + app.include_router(ws_router) except Exception as exc: logger.error(f"Failed to register route {route_def.module}.{route_def.router_attr}: {exc}") break