Skip to content

Routes registered via get_fast_api_app() return 404 despite existing in app.routes (regression in 1.19.0+) #4052

@Waldkirch13

Description

@Waldkirch13

** 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

  1. Install google-adk>=1.19.0
  2. 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,
    )
  3. Ensure agent directory exists with valid agent:
    my_agent/
    ├── __init__.py  (exports root_agent)
    └── agent.py     (defines Agent)
    
  4. Run with uvicorn:
    uvicorn app:app --host 127.0.0.1 --port 8080
  5. 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"}]}}'
  6. 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
404

AgentLoader 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 object

Expected 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    web[Component] This issue will be transferred to adk-web

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions