google / google/adk-python

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

Aperta
#4,657 3 commenti 0 reazioni 3 assegnatari Rivendicata da @GWeale Vedi su GitHub
needs review web
Lingua principale
Python
Stelle
21.5k
Fork
4k
Merge medio
1g 14h
PR unite (30g)
37

Descrizione

## 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

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.