run-llama/llama_index · error · ValueError
No tool calls found, cannot aggregate results.
Error message
No tool calls found, cannot aggregate results.
What it means
The aggregate_tool_results step expects the shared store key 'num_tool_calls' to be > 0 — it is set when the agent emits tool calls, and ctx.collect_events gathers that many ToolCallResult events. Reaching this step with num_tool_calls missing/0 means the internal event contract was broken (tool-call step skipped or events lost), so aggregation cannot proceed.
Source
Thrown at llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py:688
result_ev = ToolCallResult(
tool_name=ev.tool_name,
tool_kwargs=ev.tool_kwargs,
tool_id=ev.tool_id,
tool_output=result,
return_direct=tool.metadata.return_direct if tool else False,
)
ctx.write_event_to_stream(result_ev)
return result_ev
@step
async def aggregate_tool_results(
self, ctx: Context, ev: ToolCallResult
) -> Union[AgentInput, StopEvent, None]:
"""Aggregate tool results and return the next agent input."""
num_tool_calls = await ctx.store.get("num_tool_calls", default=0)
if num_tool_calls == 0:
raise ValueError("No tool calls found, cannot aggregate results.")
tool_call_results: list[ToolCallResult] = ctx.collect_events( # type: ignore
ev, expected=[ToolCallResult] * num_tool_calls
)
if not tool_call_results:
return None
memory: BaseMemory = await ctx.store.get("memory")
agent_name: str = await ctx.store.get("current_agent_name")
agent: BaseWorkflowAgent = self.agents[agent_name]
# track tool calls made during a .run() call
cur_tool_calls: List[ToolCallResult] = await ctx.store.get(
"current_tool_calls", default=[]
)
cur_tool_calls.extend(tool_call_results)
await ctx.store.set("current_tool_calls", cur_tool_calls)
View on GitHub (pinned to afd0fef371)
Solutions
- If you subclass or emit custom events, ensure the agent's tool-call step runs first so num_tool_calls is set in ctx.store.
- Create a fresh workflow/Context per run; do not share Context between different workflow instances.
- If not customizing internals, upgrade llama-index-core to rule out a regression and report with a minimal reproducer.
Defensive patterns
Strategy: try-catch
Try / catch
try:
result = await wf.run(user_msg=q)
except ValueError as e:
if "No tool calls found" in str(e):
# internal invariant break: report context instead of masking
raise RuntimeError("workflow event contract broken") from e
raise Prevention
- Do not inject ToolCallResult events into AgentWorkflow yourself.
- Use a fresh workflow instance/Context per run.
- Pin a single llama-index-core version across the environment to avoid mixed internals.
When it happens
Trigger: Not normally reachable from public API usage: it requires a ToolCallResult event to arrive while 'num_tool_calls' was never set — e.g. custom workflow steps injecting ToolCallResult events into an AgentWorkflow subclass, or a corrupted ctx.store between steps.
Common situations: Subclassing AgentWorkflow and emitting ToolCallResult manually; reusing a Context across workflows; version mismatches after upgrading llama-index-core mid-cache.
Related errors
- All agents must have a name in a multi-agent workflow
- All agents must have a description in a multi-agent workflow
- Initial state is not supported per-agent in AgentWorkflow
- Exactly one root agent must be provided
- Root agent {root_agent} not found in provided agents
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/8149f30ceef08a32.
Report an issue: GitHub.