Skip to content

tools_dict session-wide key causes cross-agent tool dispatch errors in parallel #5462

@Valwolfor

Description

@Valwolfor

temp:tools_dict session-wide key causes cross-agent tool dispatch errors in parallel graph_flow

Version

google-adk 2.0.0a2

Description

When multiple LlmAgents with tools run in parallel inside a graph_flow
(fan-out topology), all agents write their resolved tools to the same flat
session-wide key temp:tools_dict. Last-writer wins. When execute_tools
reads that key to dispatch a function call, it may pick up a different
agent's tools_dict, raising:

ValueError: Tool 'X' not found

Root cause

_call_llm_node.call_llm stores the resolved tools dict at:

invocation_context.session.state["temp:tools_dict"] = tools_dict

In a parallel graph_flow, multiple agent tasks run concurrently and all
write to this same key. _execute_tools_node.execute_tools then reads
session.state["temp:tools_dict"] — whichever agent wrote last wins,
dispatching function calls against the wrong agent's tools.

A ContextVar does not fix this: _process_agent_tools runs in the
call_llm Task while execute_tools runs in a sibling Task (not a
child). ContextVar.set() in one Task never propagates to sibling Tasks.

Workaround

Patch _process_agent_tools to snapshot the resolved tools_dict per agent
in a module-level dict keyed by agent name, then patch
handle_function_call_list_async to look up the correct dict before
forwarding. asyncio is single-threaded so there are no true write races.

_tools_by_agent: dict[str, dict] = {}

# In patched _process_agent_tools:
agent_name = invocation_context.agent.name
_tools_by_agent[agent_name] = dict(llm_request.tools_dict)

# In patched handle_function_call_list_async:
agent_name = invocation_context.agent.name
if agent_name in _tools_by_agent:
    tools_dict = _tools_by_agent[agent_name]

Steps to reproduce

1. Define a graph_flow with fan-out to 2+ LlmAgents, each with different tools.
2. Send a message that triggers tool calls from multiple agents in the same turn.
3. Observe ValueError: Tool 'X' not found from the agent whose tools_dict was overwritten.

Metadata

Metadata

Labels

core[Component] This issue is related to the core interface and implementationv2Affects only 2.0 version

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions