Skip to content

Bug: Systemic failure in parallel tool execution (dropped tools, infinite loops) due to hardcoded parts[0] indexing #6603

Description

@Harshitmishra001

🔴 Required Information

Describe the Bug:
Across several critical subsystems in the framework, there is a hardcoded assumption that the function_response always resides at index 0 of the event parts array (event.content.parts[0]). When an agent handles parallel tool calls, the model returns multiple function responses within a single turn, making the index dynamic. This hardcoded parts[0] assumption causes the framework to silently ignore, drop, or mismatch tool responses when they appear at indices other than 0.

This systemic flaw breaks telemetry tracing (spans are dropped or mismatched), causes load_artifacts to infinite loop (as seen in #5967), breaks MCP resource loading, and crashes CLI conformance tests.

Steps to Reproduce:

  1. Configure an agent with multiple tools (e.g., a custom tool and load_artifacts_tool).
  2. Prompt the agent in a way that triggers multiple tools to execute simultaneously in parallel.
  3. Observe that telemetry is only recorded for the first tool, and/or load_artifacts fails to execute because its response is located at parts[1].

Expected Behavior:
The framework should correctly iterate through event.content.parts to locate the function_response that matches the executing tool's name, allowing parallel tools to resolve correctly regardless of their position in the array.

Observed Behavior:
The framework blindly targets parts[0]. This causes subsequent tools in the parallel execution array (like load_artifacts at parts[1]) to be ignored or treated as text, leading to infinite retry loops, dropped telemetry traces, and ValueError crashes in the CLI testing framework.

Environment Details:

  • ADK Library Version: N/A (Source code level bug in main)
  • Desktop OS: N/A (Framework level)
  • Python Version: N/A

Model Information:

  • Are you using LiteLLM: Yes/No
  • Which model is being used: Any model supporting parallel function calling (e.g., gemini-1.5-pro, gemini-2.5-pro)

🟡 Optional Information

Regression:
N/A. This appears to be an architectural assumption present since parallel tools were supported.

Logs:
N/A

Screenshots / Video:
N/A

Additional Context:
To ensure this was a genuine framework bug and not an anomaly, we performed multiple rounds of rigorous verification:

  1. Mocking Failure: We initially tried to test this using ToolContext mocks, which hit JSON serialization TypeErrors, forcing us to look deeper into the actual object payloads.
  2. Custom Test Script: We built a dedicated script that programmatically constructed types.Content objects containing parallel types.Part elements. We fed this into the load_artifacts_tool logic and conclusively proved that the tool drops any function response that does not sit exactly at index 0.
  3. Full Test Suite Run: After fixing the source code locally, we ran the full pytest suite and immediately caught existing tests in test_spans.py failing. These tests were actually written around the bug (assuming index 0 was correct) and broke once the framework began properly mapping responses by name!

Minimal Reproduction Code:
This is the core issue present in tracing.py, load_artifacts_tool.py, load_mcp_resource_tool.py, and others:

# BROKEN LOGIC:
function_response = function_response_event.content.parts[0].function_response

# CORRECT LOGIC:
function_response = None
for part in function_response_event.content.parts:
    if part.function_response and part.function_response.name == tool.name:
        function_response = part.function_response
        break

(Note: I have a branch prepared with a comprehensive fix across all of the affected files, including updated unit tests in test_spans.py, and I will be opening a Pull Request to address this shortly).

How often has this issue occurred?:

  • Always (100%) when parallel tools are invoked and the target tool is not at index 0.

Metadata

Metadata

Labels

tools[Component] This issue is related to tools

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions