Skip to content

Output_Schema + Tool with structured arg [List of object] causes blank tool input [{}] and infinite loop #4868

@Krajpurohit

Description

@Krajpurohit

UDescription:
When for an LLMAgent output_schema is defined and the agent has a tool with at least one argument typed as a list or object structure, the tool receives blank/empty values for that argument. After that, the agent keeps invoking the same tool repeatedly and appears to run indefinitely.

Steps to Reproduce:
1 Create an Agent
2 Define an output_schema using a Pydantic model
3 Add a tool that accepts at least one structured arg of type list[dict[str, str]]
4 Run the agent with a prompt that should cause it to call the tool with populated values
5 Observe that the tool is invoked with blank/empty values and then continues being called repeatedly instead of the agent completing normally

Expected Behavior:
The agent should construct and pass proper values to the tool argument, execute the tool normally, and then return a final response that conforms to the defined output_schema.

Observed Behavior:
The tool is called with blank/empty values for the structured argument. After that, the agent continues calling the tool repeatedly and does not terminate normally, appearing to enter an infinite loop.

Environment Details:

  • ADK Library Version (pip show google-adk): Reproduced across versions 1.23.0 to 1.27.2
  • Desktop OS: Windows
  • Python Version (python -V): 3.12

Model Information:

  • Are you using LiteLLM: No
  • Which model is being used: gemini-2.5-flash

Screenshots:

🟡 Optional Information

Regression:
I tested this across multiple ADK versions from 1.23.0 to 1.27.2, and the issue reproduces in all of them. I have not found a version where this works correctly in my setup.

Minimal Reproduction Code:
Please provide a code snippet or a link to a Gist/repo that isolates the issue.

from google.adk.agents.llm_agent import Agent
from dotenv import load_dotenv
from google.adk.tools import ToolContext
from pydantic import BaseModel, Field
import random

load_dotenv()

class AgentResponse(BaseModel):
    """Structured agent output with the main response separated from facts."""
    response: str = Field(
        description="Friendly user-facing summary of the fruit basket total."
    )
    facts: list[str] | None = Field(
        description="Exactly 3 short and fun fruit facts related to the selected fruits."
    )

def fruits_to_cost(tool_context: ToolContext, fruits: list[dict[str, str]]) -> str:
    """
    Takes a list of fruit dicts and returns a total cost.
    If qty or cost-per-piece is missing, a random value is generated.
    The agent can build this fruit list even from a short user request.
    Example user request: "Make me a colorful tropical fruit basket"
    Example tool input: [{"name": "Mango", "qty": "3", "cost-per-piece": "1.80"}, {"name": "Pineapple"}, {"name": "Kiwi"}]
    Returns: "Estimated basket total for Mango x3 @ $1.80, Pineapple x4 @ $2.10, Kiwi x2 @ $0.90 is $15.00"
    """
    if not fruits:
        return "No fruits were provided, so the total is $0.00"

    basket_lines: list[str] = []
    total_cost = 0.0

    for fruit in fruits:
        name = fruit.get("name", "Unknown Fruit")
        qty = int(fruit.get("qty", str(random.randint(1, 6))))
        cost_per_piece = float(
            fruit.get("cost-per-piece", f"{random.uniform(0.4, 2.5):.2f}")
        )
        line_total = qty * cost_per_piece
        total_cost += line_total
        basket_lines.append(f"{name} x{qty} @ ${cost_per_piece:.2f}")

    return (
        f"Estimated basket total for ( {', '.join(basket_lines)} ) is ${total_cost:.2f}"
    )


root_agent = Agent(
    model='gemini-2.5-flash',
    name='root_agent',
    description=("Dynamic fruit basket cost calculator"),
    instruction=(
        "## Role\n"
        "You are responsible for creating a lively fruit basket estimate. "
        "The user may give only a short request, such as a mood, color, occasion, or just one fruit name. "
        "In that case, infer a suitable fruit basket yourself and call the tool 'fruits_to_cost' with a list of fruit dictionaries. "
        "Each fruit can include 'name', and may optionally include 'qty' and 'cost-per-piece'. "
        "If some values are missing, the tool will generate them dynamically, so do not ask the user for extra details unless the request is truly unclear. "
        "Choose fruits that match the user intent and make the basket feel vivid and practical. "
        "Then return a cheerful summary in 'response' and exactly 3 engaging fruit facts in 'facts'."
    ),
    tools=[fruits_to_cost],
    output_schema=AgentResponse
)

How often has this issue occurred?:

  • Always (100%)

Metadata

Metadata

Labels

core[Component] This issue is related to the core interface and implementation

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions