{"record":{"id":"e8d306447ca4c612","repo":"run-llama/llama_index","slug":"invalid","errorCode":null,"errorMessage":"Invalid","messagePattern":"Invalid","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/llms/function_calling.py","lineNumber":258,"sourceCode":"            call_tool_with_selection(tool_call, tools, verbose=verbose)\n            for tool_call in tool_calls\n        ]\n        tool_outputs_with_error = [\n            tool_output for tool_output in tool_outputs if tool_output.is_error\n        ]\n        if error_on_tool_error and len(tool_outputs_with_error) > 0:\n            error_text = \"\\n\\n\".join(\n                [tool_output.content for tool_output in tool_outputs]\n            )\n            raise ValueError(error_text)\n        elif allow_parallel_tool_calls:\n            output_text = \"\\n\\n\".join(\n                [tool_output.content for tool_output in tool_outputs]\n            )\n            return AgentChatResponse(response=output_text, sources=tool_outputs)\n        else:\n            if len(tool_outputs) > 1:\n                raise ValueError(\"Invalid\")\n            elif len(tool_outputs) == 0:\n                return AgentChatResponse(\n                    response=response.message.content or \"\", sources=tool_outputs\n                )\n\n            return AgentChatResponse(\n                response=tool_outputs[0].content, sources=tool_outputs\n            )\n\n    async def apredict_and_call(\n        self,\n        tools: Sequence[\"BaseTool\"],\n        user_msg: Optional[Union[str, ChatMessage]] = None,\n        chat_history: Optional[List[ChatMessage]] = None,\n        verbose: bool = False,\n        allow_parallel_tool_calls: bool = False,\n        error_on_no_tool_call: bool = True,\n        error_on_tool_error: bool = False,","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/llms/function_calling.py#L240-L276","documentation":"Poorly-named ValueError('Invalid') raised in the sync predict_and_call() flow: after executing the model's tool calls, if more than one tool output was produced while allow_parallel_tool_calls=False, the code cannot fold multiple results into a single AgentChatResponse and raises. It signals the model issued parallel tool calls even though they were disallowed.","triggerScenarios":"llm.predict_and_call(tools, user_msg, allow_parallel_tool_calls=False) where the underlying model returns multiple tool_calls in one response — possible with models like GPT-4o that like parallel calls, or when the provider ignored the parallel-calls flag. get_tool_calls_from_response returns several selections, all execute, and len(tool_outputs) > 1 hits the branch.","commonSituations":"Agents built on predict_and_call with default flags against models that aggressively batch tool calls; provider config that enables parallel function calling at the API level (e.g. OpenAI parallel_tool_calls=True) contradicting the llama-index flag.","solutions":["Pass allow_parallel_tool_calls=True if your agent can handle multiple results.","Disable parallel tool calls at the provider level (e.g. OpenAI client with parallel_tool_calls=False) so the model returns one call per turn.","Catch ValueError here and retry with a stronger instruction, or use a higher-level agent runner that normalizes multi-call responses."],"exampleFix":"# before\nresp = llm.predict_and_call(tools, user_msg='do both tasks')  # model returns 2 tool calls -> ValueError('Invalid')\n\n# after\nresp = llm.predict_and_call(tools, user_msg='do both tasks', allow_parallel_tool_calls=True)","handlingStrategy":"fallback","validationCode":"try:\n    resp = llm.predict_and_call(tools, user_msg, allow_parallel_tool_calls=True)\nexcept ValueError:\n    resp = llm.predict_and_call(tools, user_msg, allow_parallel_tool_calls=False)","typeGuard":null,"tryCatchPattern":"try:\n    resp = llm.predict_and_call(tools, user_msg, allow_parallel_tool_calls=False)\nexcept ValueError as e:\n    if str(e) == 'Invalid':\n        resp = llm.predict_and_call(tools, user_msg, allow_parallel_tool_calls=True)\n    else:\n        raise","preventionTips":["Default to allow_parallel_tool_calls=True with models that batch calls","Disable parallel calls at the provider (parallel_tool_calls=False) when you must have one call per turn","Test agent tool flows against your specific model's multi-call behavior"],"tags":["llm","function-calling","tools","parallel-tool-calls"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}