Skip to content

list_agents() returns non-agent directories in /list-apps endpoint #4647

Closed

Description

@markadelnawar

🔴 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:

  1. 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
  1. Run adk web . from my_project/
  2. Open the web UI
  3. Observe that utils, data, and tmp appear in the agent selector alongside my_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)
Image

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%)

Activity

  1. added
    web[Component] This issue will be transferred to adk-web
    on Feb 28, 2026
  2. added theissue type on Feb 28, 2026
  3. surajksharma07 commented on Feb 28, 2026

    @surajksharma07
    Collaborator

    @markadelnawar The root cause is in AgentLoader.list_agents() at cli/utils/agent_loader.py:338–344 — the filter only checks isdir, hidden prefix, and __pycache__, with no validation that the directory actually contains agent.py, __init__.py, or root_agent.yaml.

    Adding those three Path.exists() checks to the list comprehension (exactly as PR #4648 does) is the correct fix.

    Confirmed reproducible on v1.26.0.

    Team is looking more into it.

  4. added a commit that references this issue on Mar 4, 2026
    3b5937f
  5. added a commit that references this issue on Mar 5, 2026
    00ec4b4
  6. added a commit that references this issue on Aug 11, 2026
    6cd52e8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

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