run-llama/llama_index · error · ValueError

LLM is required to get tool calls

Error message

LLM is required to get tool calls

What it means

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.

Source

Thrown at llama-index-core/llama_index/core/program/utils.py:202

    Returns:
        Union[BaseModel, List[BaseModel]]: Processed object(s)

    """
    if flexible_mode:
        # Create flexible version of model that allows partial responses
        partial_output_cls = create_flexible_model(output_cls)
    else:
        partial_output_cls = output_cls  # type: ignore

    if isinstance(chat_response, CompletionResponse):
        output_cls_args = [chat_response.text]
    # Get tool calls from response, if there are any
    elif not chat_response.message.additional_kwargs.get("tool_calls"):
        output_cls_args = [chat_response.message.content or ""]
    else:
        tool_calls: List[ToolSelection] = []
        if not llm:
            raise ValueError("LLM is required to get tool calls")

        if isinstance(chat_response.message.additional_kwargs.get("tool_calls"), list):
            assert isinstance(llm, FunctionCallingLLM)
            tool_calls = llm.get_tool_calls_from_response(
                chat_response, error_on_no_tool_call=False
            )

        if len(tool_calls) == 0:
            # If no tool calls, return single blank output class
            return partial_output_cls()

        # Extract arguments from tool calls
        output_cls_args = [call.tool_kwargs for call in tool_calls]  # type: ignore

    # Try to parse objects, handling potential incomplete JSON
    objects = []
    for output_cls_arg in output_cls_args:
        try:

View on GitHub (pinned to afd0fef371)

Solutions

  1. Pass llm=<your FunctionCallingLLM> whenever the response may contain tool calls.
  2. Ensure the LLM you pass is a FunctionCallingLLM subclass (the code asserts this for list tool_calls).
  3. If tool calls are unexpected, inspect why additional_kwargs contains tool_calls (e.g. wrong response object passed).

Example fix

# before
result = _process_output(chat_response, output_cls)  # llm omitted
# after
result = _process_output(chat_response, output_cls, llm=my_function_calling_llm)
Defensive patterns

Strategy: type-guard

Validate before calling

from llama_index.core.llms.function_calling import FunctionCallingLLM
from llama_index.core.llms import ChatResponse

likely_tool_calls = (
    isinstance(chat_response, ChatResponse)
    and bool(chat_response.message.additional_kwargs.get("tool_calls"))
)
if likely_tool_calls and not isinstance(llm, FunctionCallingLLM):
    raise ValueError("a FunctionCallingLLM is required to parse tool calls")

Type guard

from llama_index.core.llms.function_calling import FunctionCallingLLM

def can_parse_tool_calls(llm) -> bool:
    return isinstance(llm, FunctionCallingLLM)

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15). Data as JSON: /api/errors/54dadf6347fb42ac. Report an issue: GitHub.