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
- Register the missing function with the exact name the LLM sees: manager.register_function(name, input_model, function)
- Make the registration name and the tool schema name identical strings
- Re-list registered names (manager._tools.keys() or your registry) to spot mismatches
- 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
- Build the LLM tool schemas and the registry from one source of truth (name -> model -> fn)
- Register every advertised tool before the first completion call
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
- Failed to parse arguments for function '{function_name}': {e
- TemplateEngineConfig.template_manager '{strategy}' is not re
- request_id needs to be passed as a keyword argument
- TokenizerConfig.type '{strategy}' is not registered in the T
- No storage account blob url provided for blob storage.
AI-assisted analysis of microsoft/graphrag@f40e9a26ce (2026-08-27).
Data as JSON: /api/errors/c58276ff45a1adbb.
Report an issue: GitHub.