run-llama/llama_index · error · ValueError
Tool {tool.metadata.name} requires context. CodeActAgent onl
Error message
Tool {tool.metadata.name} requires context. CodeActAgent only supports tools that do not require context. What it means
FunctionTool.real_fn is a property returning self._real_fn; it raises ValueError when _real_fn was never set. Given __init__ enforces fn or async_fn, this only fires on improperly initialized objects: instances created via __new__ without __init__ (e.g. pickle/deserialization paths, copies), or subclasses/monkeypatching that bypass or reset __init__.
Source
Thrown at llama-index-core/llama_index/core/agent/workflow/codeact_agent.py:137
llm=llm,
code_act_system_prompt=code_act_system_prompt,
code_execute_fn=code_execute_fn,
streaming=streaming,
)
def _get_tool_fns(self, tools: Sequence[BaseTool]) -> List[Callable]:
"""Get the tool functions while validating that they are valid tools for the CodeActAgent."""
callables = []
for tool in tools:
if (
tool.metadata.name == "handoff"
or tool.metadata.name == EXECUTE_TOOL_NAME
):
continue
if isinstance(tool, FunctionTool):
if tool.requires_context:
raise ValueError(
f"Tool {tool.metadata.name} requires context. "
"CodeActAgent only supports tools that do not require context."
)
callables.append(tool.real_fn)
else:
raise ValueError(
f"Tool {tool.metadata.name} is not a FunctionTool. "
"CodeActAgent only supports Functions and FunctionTools."
)
return callables
def _extract_code_from_response(self, response_text: str) -> Optional[str]:
"""
Extract code from the LLM response using XML-style <execute> tags.
Args:View on GitHub (pinned to afd0fef371)
Solutions
- Construct FunctionTool properly through its constructor so _real_fn is set.
- For pickling, implement __getstate__/__setstate__ (or reduce) that re-runs construction with the original fn reference rather than raw state.
- Access the underlying callable defensively: getattr(tool, '_real_fn', None) with a fallback to tool.fn.
- In subclasses, ensure super().__init__(fn=..., metadata=...) is invoked.
Example fix
# before
tool = pickle.loads(payload) # instance whose __init__ never ran
fn = tool.real_fn # ValueError: Real function is not set!
# after
class PickleableFunctionTool(FunctionTool):
def __getstate__(self):
return {"fn": self._fn, "metadata": self._metadata}
def __setstate__(self, state):
self.__init__(fn=state["fn"], metadata=state["metadata"])
fn = tool.real_fn # ok Defensive patterns
Strategy: type-guard
Validate before calling
real = getattr(tool, '_real_fn', None)
if real is None:
raise TypeError('tool not properly initialized; reconstruct via FunctionTool(...)')
use = real Type guard
def tool_has_real_fn(tool) -> bool:
return getattr(tool, "_real_fn", None) is not None Try / catch
try:
fn = tool.real_fn
except ValueError:
fn = tool.fn # sync fallback or re-init the tool Prevention
- Implement __getstate__/__setstate__ on pickled FunctionTool subclasses to re-run __init__.
- Avoid creating tools via __new__ or mocks that skip initialization.
- Call super().__init__ in subclasses.
When it happens
Trigger: Accessing tool.real_fn on a FunctionTool reconstructed from pickle without running __init__; deep-copying or deserializing tools from agent dumps; a subclass overriding __init__ and forgetting to set _real_fn; test doubles calling FunctionTool.__new__.
Common situations: Persisting/loading agents that contain FunctionTools across processes; multiprocessing workers that unpickle tools; mock frameworks creating allocation-only instances; refactors splitting initialization from construction.
Related errors
- Git command failed: {result.stderr}
- Max iterations of {max_iterations} reached! Either something
- No tool calls found, cannot aggregate results.
- Tool {tool.metadata.name} is not a FunctionTool. CodeActAgen
- code_execute_fn must be provided for CodeActAgent
AI-assisted analysis of run-llama/llama_index@afd0fef371 (2026-08-15).
Data as JSON: /api/errors/f3bd0ed493c981d9.
Report an issue: GitHub.