Skip to content

adk api_server --a2a silently mounts no A2A routes: UnboundLocalError on json in get_fast_api_app #6332

Description

@szamcsi-at-google

🔴 Required Information

Describe the Bug:

Running adk api_server --a2a against an agent directory that contains an
agent.json (agent card) fails to set up the A2A endpoint and starts the server
without any A2A routes. The failure is swallowed by a try/except and only
appears as one ERROR log line, so from the user's side --a2a silently does
nothing.

Root cause is a shadowed import in src/google/adk/cli/fast_api.py:
get_fast_api_app() imports json at module scope (line 19) but also has a
function-local import json (line 748, in the gemini_enterprise_app_name
block). Because that local import exists anywhere in the function, Python treats
json as local for the entire function, so the earlier json.load(f) that
reads agent.json (line 720) raises UnboundLocalError before the local import
is ever reached.

Steps to Reproduce:

  1. Create an agent folder agents/hello/ with agent.py exposing
    root_agent = LlmAgent(...) and an agents/hello/agent.json (any valid A2A
    AgentCard JSON).
  2. Run adk api_server --a2a agents.
  3. Probe the A2A card endpoint:
    curl -s -o /dev/null -w "%{http_code}\n" \
      http://127.0.0.1:8000/a2a/hello/.well-known/agent-card.json
  4. Observe the startup ERROR log (below) and a 404 from the card endpoint.

Expected Behavior:

adk api_server --a2a mounts the A2A routes (/a2a/<app> and
/a2a/<app>/.well-known/agent-card.json) for every agent folder that has an
agent.json.

Observed Behavior:

The server starts (Uvicorn running) but A2A setup fails and the routes are
never added — the card endpoint returns 404, and there is no A2A JSON-RPC
endpoint. The ADK REST endpoints (/list-apps, /run_sse) work normally.
Startup log:

ERROR - fast_api.py:739 - Failed to setup A2A agent hello:
cannot access local variable 'json' where it is not associated with a value

Environment Details:

  • ADK Library Version (pip show google-adk): 2.2.0 (verified against the
    pristine google_adk-2.2.0-py3-none-any.whl; fast_api.py lines 19 / 720 / 748)
  • Desktop OS: Linux
  • Python Version (python -V): 3.13

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: N/A — CLI/serving bug, independent of the model

🟡 Optional Information

Additional Context:

The --a2a A2A-setup block and the redundant import live in the same function
(get_fast_api_app):

# src/google/adk/cli/fast_api.py  (google-adk 2.2.0)
import json                                   # line 19  (module scope)

def get_fast_api_app(...):
    ...
    # A2A setup, per agent folder with an agent.json:
    with (p / "agent.json").open("r", encoding="utf-8") as f:
        data = json.load(f)                   # line 720 -> UnboundLocalError
        agent_card = AgentCard(**data)
    ...
    if gemini_enterprise_app_name:
        ...
        import inspect
        import json                           # line 748 -> makes `json` function-local

Suggested fix — remove the redundant function-local import (the module-level
import json at line 19 already covers it):

     import inspect
-    import json

     from google.adk.agents import Agent

Confirmed locally: with line 748 removed, --a2a mounts both routes and the card
endpoint returns 200.

This is distinct from the a2a-sdk 1.x ModuleNotFoundError: No module named 'a2a.server.apps' startup crash noted in #6220 — that is a version-pin problem;
this is a pure Python scoping bug that fails even on the supported a2a-sdk 0.3.x
line (repro'd with a2a-sdk 0.3.26). Surfaced while building a hybrid Agent Engine
deployment (streamQuery + A2A); see companion issue #<HYBRID_ISSUE>.

Minimal Reproduction Code:

The fix is the one-line diff above; the trigger is any agent folder with an
agent.json served via adk api_server --a2a.

How often has this issue occurred?:

  • Always (100%) — deterministic whenever an agent.json is present under --a2a.

Metadata

Metadata

Assignees

Labels

a2a[Component] This issue is related a2a support inside ADK.

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions