google / google/adk-python

Playground eval history: clicking failed eval result crashes with 'e is not iterable' in formatToolUses

Abierto
#4,657 3 comentarios 0 reacciones 3 asignados Reclamado por @GWeale Ver en GitHub
needs review web
Lenguaje dominante
Python
Estrellas
21.5k
Forks
4k
Merge medio
1 d 14 h
PR fusionados (30 d)
37

Descripción

## Describe the bug

When viewing eval results in the ADK playground web UI, clicking on a **failed** eval case result (to view the session details) crashes with a JavaScript error. Clicking on **passed** eval results works correctly.

**Error from browser console:**

```
Uncaught TypeError: e is not iterable
at t.formatToolUses (main-QQBY56NS.js:4105:21033)
at t.addEvalFieldsToBotEvent (main-QQBY56NS.js:4105:21654)
at t.addEvalCaseResultToEvents (main-QQBY56NS.js:4105:21447)
```

## Root cause

In the eval tab component, `addEvalFieldsToBotEvent` calls `formatToolUses` when a metric has `evalStatus === 2` (fail) and the metric name is `tool_trajectory_avg_score`:

```javascript
// addEvalFieldsToBotEvent calls:
e.actualInvocationToolUses = this.formatToolUses(A.actualInvocation.intermediateData.toolUses)
e.expectedInvocationToolUses = this.formatToolUses(A.expectedInvocation.intermediateData.toolUses)
```

`formatToolUses` iterates its argument with `for...of` but does not guard against `null`/`undefined`:

```javascript
formatToolUses(e) {
let A = [];
for (let i of e) // crashes if e is null/undefined
A.push({name: i.name, args: i.args});
return A;
}
```

When eval cases don't include `tool_uses` in their `intermediate_data` (or when `intermediateData.toolUses` is serialized as `null`), `expectedInvocation.intermediateData.toolUses` is `null`, causing the crash.

This code path is only reached for **failed** evals because the `tool_trajectory_avg_score` status check (`evalStatus === 2`) only triggers for failures. Passed evals never enter this branch.

## Steps to reproduce

1. Create a minimal agent that uses `AgentTool`:

```python
from google.adk.agents import Agent, SequentialAgent
from google.adk.tools.agent_tool import AgentTool

sub_agent = Agent(name="sub", model="gemini-2.5-flash", instruction="Say hello")
workflow = SequentialAgent(name="workflow", sub_agents=[sub_agent])
root_agent = Agent(
name="my_agent",
model="gemini-2.5-flash",
instruction="Use workflow tool to respond.",
tools=[AgentTool(agent=workflow)],
)
```

2. Create an evalset file (`my_eval.evalset.json`) **without** expected `tool_uses`:

```json
{
"eval_set_id": "my_eval",
"eval_cases": [
{
"eval_id": "simple_test",
"conversation": [
{
"user_content": {
"parts": [{"text": "Hello"}]
}
}
],
"session_input": {
"app_name": "my_agent",
"user_id": "test_user",
"state": {}
}
}
]
}
```

3. Start the playground: `adk web ./agents/ --port 8501`
4. Go to the Eval tab, select `my_eval`, select the test case, run with `tool_trajectory_avg_score` metric
5. After the eval completes, go to the History section
6. Click on the result button for a **FAIL** entry -- the UI crashes with the error above

## Expected behavior

Clicking on failed eval results should display the session details, same as for passed results.

## Suggested fix

Add a null guard in `formatToolUses`:

```javascript
formatToolUses(e) {
if (!e) return [];
let A = [];
for (let i of e) A.push({name: i.name, args: i.args});
return A;
}
```

## Environment

- `google-adk` version: 1.25.1
- Python: 3.13
- Browser: Chrome (latest)
- OS: macOS

Guía de contribución

Abrir la guía de contribución

Evaluación

Este issue todavía no se ha evaluado.

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.