microsoft/graphrag · error · ValueError

Function '{function_name}' not registered.

Error message

Function '{function_name}' not registered.

What it means

FunctionToolManager.call_functions iterates tool_calls from the LLM response and looks each function name up in the registered _tools dict. If the model emitted a function name that was never registered via register_function, a ValueError is raised.

Source

Thrown at packages/graphrag-llm/graphrag_llm/utils/function_tool_manager.py:119

        -------
            list[ToolMessage]
                The list of tool response messages to be added to the message history.
        """
        if not response.choices[0].message.tool_calls:
            return []

        tool_messages: list[ToolMessage] = []

        for tool_call in response.choices[0].message.tool_calls:
            if tool_call.type != "function":
                continue
            tool_id = tool_call.id
            function_name = tool_call.function.name
            function_args = tool_call.function.arguments

            if function_name not in self._tools:
                msg = f"Function '{function_name}' not registered."
                raise ValueError(msg)

            tool_def = self._tools[function_name]
            input_model = tool_def["input_model"]
            function = tool_def["function"]

            try:
                parsed_args_dict = json.loads(function_args)
                input_model_instance = input_model(**parsed_args_dict)
            except Exception as e:
                msg = f"Failed to parse arguments for function '{function_name}': {e}"
                raise ValueError(msg) from e

            result = function(input_model_instance)
            tool_messages.append({
                "content": result,
                "tool_call_id": tool_id,
            })

View on GitHub (pinned to f40e9a26ce)

Solutions

  1. Register the missing function with the exact name the LLM sees: manager.register_function(name, input_model, function)
  2. Make the registration name and the tool schema name identical strings
  3. Re-list registered names (manager._tools.keys() or your registry) to spot mismatches
  4. If the model hallucinates the name, tighten the tool descriptions/prompt

Example fix

# before
manager.register_function('get_weather', GetWeatherInput, get_weather)
# but LLM tool schema says 'lookup_weather' -> ValueError

# after
manager.register_function('lookup_weather', GetWeatherInput, get_weather)
Defensive patterns

Strategy: validation

Validate before calling

registered = set(manager._tools)  # or expose a public list
for call in response.tool_calls:
    assert call.function.name in registered, f"unregistered tool {call.function.name}"

Type guard

def all_tools_registered(manager, response) -> bool:
    return all(c.function.name in manager._tools for c in response.tool_calls or [])

Try / catch

try:
    manager.call_functions(response)
except ValueError as e:
    if 'not registered' in str(e):
        # skip/acknowledge unknown tool and continue the loop
        ...
    else:
        raise

Prevention

When it happens

Trigger: Calling call_functions on a response whose tool_calls reference a function you never registered, or registered under a different name than the one given to the LLM's tools schema.

Common situations: Registering the Pydantic input model under one name but telling the LLM a different tool name, adding a tool to the LLM prompt but forgetting register_function, or the model hallucinating a plausible tool name.

Related errors


AI-assisted analysis of microsoft/graphrag@f40e9a26ce (2026-08-27). Data as JSON: /api/errors/c58276ff45a1adbb. Report an issue: GitHub.