-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Description
** Please make sure you read the contribution guide and file the issues in the right place. **
Contribution guide.
Describe the bug
Routes registered via get_fast_api_app() exist in the application's route list but fail to match incoming requests, resulting in 404 errors for /run, /run_sse, and /run_live endpoints. This is a regression introduced in version 1.19.0.
The routes are correctly added to app.routes with proper path and HTTP methods, but Starlette's routing mechanism fails to match them during request dispatch.
To Reproduce
- Install
google-adk>=1.19.0 - Create a FastAPI app using
get_fast_api_app():from google.adk.cli.fast_api import get_fast_api_app app = get_fast_api_app( agents_dir=".", session_service_uri="sqlite:///:memory:", allow_origins=["*"], web=True, )
- Ensure agent directory exists with valid agent:
my_agent/ ├── __init__.py (exports root_agent) └── agent.py (defines Agent) - Run with uvicorn:
uvicorn app:app --host 127.0.0.1 --port 8080
- POST to
/run:curl -X POST http://127.0.0.1:8080/run \ -H "Content-Type: application/json" \ -d '{"app_name": "my_agent", "user_id": "test", "session_id": "test", "new_message": {"role": "user", "parts": [{"text": "hello"}]}}'
- Observe 404 response.
Debugging Evidence
Routes exist at import time:
>>> import app
>>> [r.path for r in app.app.routes if 'run' in getattr(r, 'path', '')]
['/run', '/run_sse', '/run_live']Route object is correctly configured:
>>> r = [r for r in app.app.routes if getattr(r, 'path', '') == '/run'][0]
>>> print('Path:', r.path, 'Methods:', r.methods, 'Type:', type(r))
Path: /run Methods: {'POST'} Type: <class 'fastapi.routing.APIRoute'>But TestClient requests fail:
>>> from starlette.testclient import TestClient
>>> client = TestClient(app.app)
>>> client.post('/run', json={...}).status_code
404AgentLoader works correctly:
>>> from google.adk.cli.fast_api import AgentLoader
>>> loader = AgentLoader('.')
>>> loader.list_agents()
['my_agent']
>>> loader.load_agent('my_agent')
# Returns valid Agent objectExpected behavior
POST requests to /run, /run_sse, and /run_live should be handled by the registered ADK routes and return valid responses.
Screenshots
N/A
Desktop (please complete the following information):
- OS: Windows 11
- Python version: 3.11 / 3.13 (tested both)
- ADK version: Tested 1.19.0, 1.20.0, 1.21.0 (all broken); 1.18.0 works
Model Information:
- Are you using LiteLLM: No
- Which model is being used: gemini-2.5-pro (but issue occurs before model invocation)
Additional context
Version Matrix:
| google-adk | FastAPI | Starlette | Status |
|---|---|---|---|
| 1.18.0 | 0.118.3 | 0.48.0 | Working |
| 1.19.0 | 0.118.3 | 0.48.0 | Broken |
| 1.20.0 | 0.118.3 | 0.48.0 | Broken |
| 1.21.0 | 0.118.3 | 0.48.0 | Broken |
| 1.21.0 | 0.123.10 | 0.50.0 | Broken |
Pinning Starlette/FastAPI to older versions does not fix the issue.
Likely Root Cause:
The 1.19.0 release notes state:
"Reduce ADK API server startup latency by lazy loading ADK web"
This optimization likely defers route registration in a way that breaks Starlette's route compilation/matching. Routes appear in app.routes but are not properly compiled into Starlette's internal routing table.
Current Workaround:
Pin google-adk to version 1.18.0:
google-adk==1.18.0