From d0ae93a422af81da040e7bc6ec7d5880e31a1dc6 Mon Sep 17 00:00:00 2001 From: Agent Zero Date: Mon, 27 Jul 2026 01:48:18 +0200 Subject: [PATCH] =?UTF-8?q?fix:=20WebSocket=20403=20=E2=80=94=20per-route?= =?UTF-8?q?=20require=5Factive=5Fplugin=20instead=20of=20router-level?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Router-level dependencies=[Depends(require_active_plugin)] was applied to ALL routes including WebSocket. Now adding the dependency per-HTTP-route only, WebSocket routes are skipped entirely. --- app/main.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/app/main.py b/app/main.py index 544698b..d42268d 100644 --- a/app/main.py +++ b/app/main.py @@ -436,20 +436,21 @@ def create_app() -> FastAPI: router_module = importlib.import_module(route_def.module) router = getattr(router_module, route_def.router_attr) # 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. + # and add active-plugin check per-route (not router-level) + # so WebSocket routes are NOT affected. from starlette.routing import WebSocketRoute + from fastapi import APIRouter as _AR + plugin_dep = Depends(require_active_plugin(plugin_name)) for route in router.routes: if isinstance(route, WebSocketRoute): - continue + continue # WebSocket: no wrap, no plugin check if hasattr(route, 'endpoint'): route.endpoint = wrap_plugin_route(route.endpoint) - # Add active-plugin check as a router-level dependency - # (require_active_plugin skips WebSocket requests internally) - app.include_router( - router, - dependencies=[Depends(require_active_plugin(plugin_name))], - ) + # Add require_active_plugin to each HTTP route's dependencies + if not hasattr(route, 'dependencies'): + route.dependencies = [] + route.dependencies.append(plugin_dep) + app.include_router(router) except Exception as exc: logger.error(f"Failed to register route {route_def.module}.{route_def.router_attr}: {exc}") break