{"record":{"id":"54dadf6347fb42ac","repo":"run-llama/llama_index","slug":"llm-is-required-to-get-tool-calls","errorCode":null,"errorMessage":"LLM is required to get tool calls","messagePattern":"LLM is required to get tool calls","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"llama-index-core/llama_index/core/program/utils.py","lineNumber":202,"sourceCode":"    Returns:\n        Union[BaseModel, List[BaseModel]]: Processed object(s)\n\n    \"\"\"\n    if flexible_mode:\n        # Create flexible version of model that allows partial responses\n        partial_output_cls = create_flexible_model(output_cls)\n    else:\n        partial_output_cls = output_cls  # type: ignore\n\n    if isinstance(chat_response, CompletionResponse):\n        output_cls_args = [chat_response.text]\n    # Get tool calls from response, if there are any\n    elif not chat_response.message.additional_kwargs.get(\"tool_calls\"):\n        output_cls_args = [chat_response.message.content or \"\"]\n    else:\n        tool_calls: List[ToolSelection] = []\n        if not llm:\n            raise ValueError(\"LLM is required to get tool calls\")\n\n        if isinstance(chat_response.message.additional_kwargs.get(\"tool_calls\"), list):\n            assert isinstance(llm, FunctionCallingLLM)\n            tool_calls = llm.get_tool_calls_from_response(\n                chat_response, error_on_no_tool_call=False\n            )\n\n        if len(tool_calls) == 0:\n            # If no tool calls, return single blank output class\n            return partial_output_cls()\n\n        # Extract arguments from tool calls\n        output_cls_args = [call.tool_kwargs for call in tool_calls]  # type: ignore\n\n    # Try to parse objects, handling potential incomplete JSON\n    objects = []\n    for output_cls_arg in output_cls_args:\n        try:","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/run-llama/llama_index/blob/afd0fef371831f9bda13e5af7167cf4e981278ab/llama-index-core/llama_index/core/program/utils.py#L184-L220","documentation":"In _process_output (utils.py), when a chat response carries tool_calls in additional_kwargs, the helper must ask the LLM to convert them into ToolSelection objects via llm.get_tool_calls_from_response. That method only exists on FunctionCallingLLM instances, so llm must be provided and of that type; otherwise this ValueError fires. The llm parameter also serves as the isinstance assertion target.","triggerScenarios":"Processing a chat_response whose message.additional_kwargs['tool_calls'] is a list while llm=None; common when calling the program's internal output-processing helper directly or when a program is constructed without forwarding the LLM.","commonSituations":"Using a non-function-calling LLM that nevertheless echoes tool-call-like payloads; partial or streaming responses routed through PydanticProgram output processing without the llm argument; custom agents reusing _process_output.","solutions":["Pass llm=<your FunctionCallingLLM> whenever the response may contain tool calls.","Ensure the LLM you pass is a FunctionCallingLLM subclass (the code asserts this for list tool_calls).","If tool calls are unexpected, inspect why additional_kwargs contains tool_calls (e.g. wrong response object passed)."],"exampleFix":"# before\nresult = _process_output(chat_response, output_cls)  # llm omitted\n# after\nresult = _process_output(chat_response, output_cls, llm=my_function_calling_llm)","handlingStrategy":"type-guard","validationCode":"from llama_index.core.llms.function_calling import FunctionCallingLLM\nfrom llama_index.core.llms import ChatResponse\n\nlikely_tool_calls = (\n    isinstance(chat_response, ChatResponse)\n    and bool(chat_response.message.additional_kwargs.get(\"tool_calls\"))\n)\nif likely_tool_calls and not isinstance(llm, FunctionCallingLLM):\n    raise ValueError(\"a FunctionCallingLLM is required to parse tool calls\")","typeGuard":"from llama_index.core.llms.function_calling import FunctionCallingLLM\n\ndef can_parse_tool_calls(llm) -> bool:\n    return isinstance(llm, FunctionCallingLLM)","tryCatchPattern":null,"preventionTips":["Always thread the llm through when post-processing chat responses that may contain tool calls.","Check additional_kwargs['tool_calls'] before invoking tool-call processing."],"tags":["runtime","tool-calls","function-calling","validation"],"backgroundTag":null,"analyzedSha":"afd0fef371831f9bda13e5af7167cf4e981278ab","analyzedAt":"2026-08-15T05:42:58.429Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}