Repository navigation
dev-ui 404s with url_prefix behind a prefix-stripping proxy since 2.11.0聽#7439
Description
馃敶 Required Information
Describe the Bug:
Since 2.11.0, which derives FastAPI's root_path from url_prefix (#7071), the dev UI returns 404 when the app runs behind a proxy that strips the prefix, the setup #7071 was aimed at. API routes such as /list-apps still work, only /dev-ui/ breaks.
Steps to Reproduce:
- Build the app with
get_fast_api_app(agents_dir=..., web=True, url_prefix="/adk")(oradk web --url_prefix /adk). - Request
/dev-ui/, which is what a proxy forwards forhttps://host/adk/dev-ui/after stripping the prefix.
Expected Behavior:
The dev UI's index.html is served, as on 2.10.0.
Observed Behavior:
/dev-ui/ returns 404, while /list-apps returns 200.
Environment Details:
- ADK Library Version: 2.11.0 (2.10.0 works)
- Desktop OS: macOS, and Linux (Cloud Run)
- Python Version: 3.13
Model Information:
- Are you using LiteLLM: No
- Which model is being used: N/A (no model call involved)
馃煛 Optional Information
Regression:
Yes, works on 2.10.0.
Additional Context:
As far as I can tell, Starlette expects scope["path"] to include root_path. Top-level routes tolerate a path without it, which is why /list-apps still matches, but Mount builds the child scope's root_path as root_path + "/dev-ui" (/adk/dev-ui). StaticFiles then can't strip that from /dev-ui/, so it looks up dev-ui/ inside the assets directory and 404s.
Resetting app.root_path = '' after get_fast_api_app() restores the 2.10 behaviour as a workaround, at the cost of the /docs fix from #7071.
Minimal Reproduction Code:
uv run --with google-adk==2.11.0 --with httpx python repro.py
import pathlib, tempfile
from fastapi.testclient import TestClient
from google.adk.cli.fast_api import get_fast_api_app
agents_dir = pathlib.Path(tempfile.mkdtemp())
(agents_dir / "my_agent").mkdir()
(agents_dir / "my_agent" / "__init__.py").write_text("from . import agent\n")
(agents_dir / "my_agent" / "agent.py").write_text(
"from google.adk.agents import Agent\n"
"root_agent = Agent(name='my_agent', model='gemini-2.5-flash')\n"
)
for url_prefix in [None, "/adk"]:
app = get_fast_api_app(agents_dir=str(agents_dir), web=True, url_prefix=url_prefix)
client = TestClient(app, follow_redirects=False)
# A proxy that strips the prefix forwards /adk/dev-ui/ as /dev-ui/
print(f"{url_prefix=}", {p: client.get(p).status_code for p in ["/list-apps", "/dev-ui/"]})# google-adk 2.10.0
url_prefix=None {'/list-apps': 200, '/dev-ui/': 200}
url_prefix='/adk' {'/list-apps': 200, '/dev-ui/': 200}
# google-adk 2.11.0
url_prefix=None {'/list-apps': 200, '/dev-ui/': 200}
url_prefix='/adk' {'/list-apps': 200, '/dev-ui/': 404}
How often has this issue occurred?:
- Always (100%)
Activity
reddynitish commentedon Oct 7, 2026
I鈥檓 interested in investigating and fixing this, if nobody has already started. I would first reproduce the reported /dev-ui/ regression, then keep the change focused on mounted static-route handling while preserving the OpenAPI/root_path behavior introduced in #7071. Validation would cover no prefix, a prefix-stripping proxy, and the existing API/docs routes.
I found no public claim or matching PR for this issue. If you or another contributor already have work in progress, please let me know so I can avoid duplication. Maintainers: is this a suitable contribution to take on?
I plan to use Codex assistance. This is an interest/coordination request; I鈥檓 prioritizing one contribution at a time rather than promising simultaneous delivery.
reddynitish commentedon Oct 7, 2026
I鈥檓 starting work on this issue now. My plan is to:
I rechecked the issue and open PRs and found no public competing claim or fix. If someone has already started privately, please flag it so we can coordinate. I鈥檓 using Codex assistance and will include the reproduction and test results in the PR.
llalitkumarrr commentedon Oct 9, 2026
Hello @MihailRussu,
Thank you for raising this issue. #7440 should resolve it, could you please take a look and test it and let us know your feedback?
fix: serve dev UI behind prefix-stripping proxies