-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
🔴 Required Information
Describe the Bug:
The /list-apps endpoint returns directories that are not valid agents. Any subdirectory inside the agents directory (e.g. tmp/, data/, utils/) is returned in the response, even when it contains no agent definition (root_agent.yaml, agent.py, or __init__.py). This affects both the ADK web UI (where non-agent directories appear in the agent selector) and any production deployment depending on this API to list available agents.
Steps to Reproduce:
- Create a project directory with a valid agent and some non-agent subdirectories:
my_project/
├── my_agent/
│ ├── __init__.py
│ └── agent.py # valid agent
├── utils/ # not an agent
├── data/ # not an agent
└── tmp/ # not an agent
- Run
adk web .frommy_project/ - Open the web UI
- Observe that
utils,data, andtmpappear in the agent selector alongsidemy_agent
Expected Behavior:
Only directories containing a valid agent definition should appear in the agent list.
Observed Behavior:
All non-hidden subdirectories are listed regardless of whether they contain an agent. Selecting a non-agent directory results in a loading error.
Environment Details:
- ADK Library Version: 1.26.0
- Desktop OS: macOS (Darwin 25.2.0)
- Python Version: 3.12.10
Model Information:
- Are you using LiteLLM: N/A
- Which model is being used: N/A (issue is in agent discovery, not model interaction)
🟡 Optional Information
Regression:
No, this has been the behavior since list_agents() was introduced. PR #3430 (closing #3429) added a list_agents_detailed() endpoint that filters properly by loading each agent, but the web UI frontend never adopted it and still calls the plain /list-apps endpoint.
Logs:
N/A - no error on the backend, the non-agent directories are simply returned in the API response.
Screenshots / Video:
(non-agent directories listed) ( from the adk web)

Additional Context:
The root cause is in AgentLoader.list_agents() which only filters by os.path.isdir(), hidden directory prefix, and __pycache__. It does not verify the directory contains a recognized agent structure (root_agent.yaml, agent.py, or __init__.py).
Related:
Minimal Reproduction Code:
from pathlib import Path
from google.adk.cli.utils.agent_loader import AgentLoader
import tempfile
with tempfile.TemporaryDirectory() as tmp:
(Path(tmp) / "real_agent").mkdir()
(Path(tmp) / "real_agent" / "__init__.py").write_text("from google.adk.agents.base_agent import BaseAgent\nclass A(BaseAgent):\n def __init__(self): super().__init__(name='a')\nroot_agent = A()")
(Path(tmp) / "not_an_agent").mkdir()
loader = AgentLoader(tmp)
print(loader.list_agents())
# Returns: ['not_an_agent', 'real_agent']
# Expected: ['real_agent']How often has this issue occurred?:
- Always (100%)