From 0d8662a877bb6414553affa2e37e7332b7f70d57 Mon Sep 17 00:00:00 2001 From: Josh Mabry Date: Fri, 11 Sep 2026 11:27:23 -0700 Subject: [PATCH] fix: the page route declares its response class, so the host's /openapi.json builds The page route was annotated `-> HTMLResponse` with HTMLResponse imported inside the router-builder function, under `from __future__ import annotations`. FastAPI resolves that string against the module's globals, can't, and infers a response model from an unresolved forward reference, which pydantic refuses when the schema is built. One such route takes the host's whole /openapi.json (and /docs) down: found in QA of protoAgent v0.164.0 on the desktop app, where it answered 500 on every agent running this plugin. The route now declares `response_class=HTMLResponse` and has no return annotation. A new test builds the schema with the plugin's routers mounted; it fails before the change. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01F2V6GRejF7mNukAoYjj2Av --- api.py | 6 +++++- tests/test_api.py | 7 +++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/api.py b/api.py index 5d3bcaf..7b05050 100644 --- a/api.py +++ b/api.py @@ -15,8 +15,12 @@ def build_view_router(cfg: dict): r = APIRouter() + # No `-> HTMLResponse` annotation: under postponed annotations it is a string FastAPI + # resolves against this MODULE's globals, where the function-local import isn't + # visible — and even with `response_class=` set, the unresolved annotation made the + # host's /openapi.json answer 500 on every agent running this plugin. @r.get("/view", response_class=HTMLResponse) - async def _view() -> HTMLResponse: + async def _view(): return HTMLResponse(PAGE) return r diff --git a/tests/test_api.py b/tests/test_api.py index 2be4643..6dfe63d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -15,6 +15,13 @@ def client(registry): return TestClient(app) +def test_the_routers_leave_the_host_schema_buildable(client): + """A page route annotated `-> HTMLResponse` with a function-local import can't be + resolved when FastAPI builds the schema, and one such route takes the host's whole + /openapi.json down (found in QA on the desktop app, 2026-09-11).""" + assert "/plugins/learning_wiki/view" in client.app.openapi()["paths"] + + def test_view_served_on_declared_public_path(client): r = client.get("/plugins/learning_wiki/view") assert r.status_code == 200