{"record":{"id":"8149f30ceef08a32","repo":"run-llama/llama_index","slug":"no-tool-calls-found-cannot-aggregate-results-8149f3","errorCode":null,"errorMessage":"No tool calls found, cannot aggregate results.","messagePattern":"No tool calls found, cannot aggregate results\\.","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py","lineNumber":688,"sourceCode":"        result_ev = ToolCallResult(\n            tool_name=ev.tool_name,\n            tool_kwargs=ev.tool_kwargs,\n            tool_id=ev.tool_id,\n            tool_output=result,\n            return_direct=tool.metadata.return_direct if tool else False,\n        )\n\n        ctx.write_event_to_stream(result_ev)\n        return result_ev\n\n    @step\n    async def aggregate_tool_results(\n        self, ctx: Context, ev: ToolCallResult\n    ) -> Union[AgentInput, StopEvent, None]:\n        \"\"\"Aggregate tool results and return the next agent input.\"\"\"\n        num_tool_calls = await ctx.store.get(\"num_tool_calls\", default=0)\n        if num_tool_calls == 0:\n            raise ValueError(\"No tool calls found, cannot aggregate results.\")\n\n        tool_call_results: list[ToolCallResult] = ctx.collect_events(  # type: ignore\n            ev, expected=[ToolCallResult] * num_tool_calls\n        )\n        if not tool_call_results:\n            return None\n\n        memory: BaseMemory = await ctx.store.get(\"memory\")\n        agent_name: str = await ctx.store.get(\"current_agent_name\")\n        agent: BaseWorkflowAgent = self.agents[agent_name]\n\n        # track tool calls made during a .run() call\n        cur_tool_calls: List[ToolCallResult] = await ctx.store.get(\n            \"current_tool_calls\", default=[]\n        )\n        cur_tool_calls.extend(tool_call_results)\n        await ctx.store.set(\"current_tool_calls\", cur_tool_calls)\n","sourceCodeStart":670,"sourceCodeEnd":706,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/agent/workflow/multi_agent_workflow.py#L670-L706","documentation":"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.","triggerScenarios":"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.","commonSituations":"Subclassing AgentWorkflow and emitting ToolCallResult manually; reusing a Context across workflows; version mismatches after upgrading llama-index-core mid-cache.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    result = await wf.run(user_msg=q)\nexcept ValueError as e:\n    if \"No tool calls found\" in str(e):\n        # internal invariant break: report context instead of masking\n        raise RuntimeError(\"workflow event contract broken\") from e\n    raise","preventionTips":["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."],"tags":["agent-workflow","internal-invariant","events","subclassing"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}