Commit 9310ba7
fix(agents): await cancelled tasks in _merge_agent_run_pre_3_11 to prevent aclose() RuntimeError
Merge #5416
### Link to Issue or Description of Change
Fixes #5297
### Description
On Python 3.10, `ParallelAgent` uses `_merge_agent_run_pre_3_11` instead of
`asyncio.TaskGroup`. When a sub-agent raises an exception, the `finally` block
cancelled all internal tasks with `task.cancel()` but **did not await them**.
This left the `process_an_agent` coroutines still executing their own `finally`
blocks — which hold references to the sub-agent async generators — when
`_run_async_impl` subsequently called `aclose()` on those generators, raising:
```
RuntimeError: aclose(): asynchronous generator is already running
```
This secondary error masked the original sub-agent exception (e.g., a
Pydantic validation failure from a structured-output agent).
**Fix:** add `await asyncio.gather(*tasks, return_exceptions=True)` after
cancellation so all tasks — including their generator cleanup — complete fully
before the caller can invoke `aclose()` on the generators.
### Changes
- `src/google/adk/agents/parallel_agent.py`: one line added to `_merge_agent_run_pre_3_11` finally block
- `tests/unittests/agents/test_parallel_agent.py`: regression test that directly exercises `_merge_agent_run_pre_3_11` with a slow generator + failing generator, then calls `aclose()` — without the fix this raises `RuntimeError`
### Testing Plan
- New test `test_merge_agent_run_pre_3_11_no_aclose_error_on_failure` added to `tests/unittests/agents/test_parallel_agent.py`
- All 9 existing parallel agent tests continue to pass
```
pytest tests/unittests/agents/test_parallel_agent.py -v
======================== 9 passed in 5.46s ===========================
```
Co-authored-by: Bo Yang <ybo@google.com>
COPYBARA_INTEGRATE_REVIEW=#5416 from Koushik-Salammagari:fix/parallel-agent-pre-311-aclose-error 1e11fd7
PiperOrigin-RevId: 9312471481 parent 90bd38f commit 9310ba7
2 files changed
Lines changed: 37 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
146 | 146 | | |
147 | 147 | | |
148 | 148 | | |
| 149 | + | |
149 | 150 | | |
150 | 151 | | |
151 | 152 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
373 | 374 | | |
374 | 375 | | |
375 | 376 | | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
0 commit comments