crewAIInc/crewAI · error · ValueError
The LlamaIndex tool does not have an fn_schema specified.
Error message
The LlamaIndex tool does not have an fn_schema specified.
What it means
After confirming the object is a llama-index BaseTool, LlamaIndexTool.from_tool requires tool.metadata.fn_schema (the pydantic schema describing the tool's arguments) because CrewAI builds its args_schema from it. Tools created without a schema — e.g. FunctionTool.from_defaults(fn=...) without explicit fn_schema on some paths, or custom tools with metadata.fn_schema left None — fail here.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/llamaindex_tool/llamaindex_tool.py:37
"""Run tool."""
tool = self.llama_index_tool
if self.result_as_answer:
return tool(*args, **kwargs).content
return tool(*args, **kwargs)
@classmethod
def from_tool(cls, tool: Any, **kwargs: Any) -> LlamaIndexTool:
from llama_index.core.tools import ( # type: ignore[import-not-found]
BaseTool as LlamaBaseTool,
)
if not isinstance(tool, LlamaBaseTool):
raise ValueError(f"Expected a LlamaBaseTool, got {type(tool)}")
if tool.metadata.fn_schema is None:
raise ValueError(
"The LlamaIndex tool does not have an fn_schema specified."
)
args_schema = cast(type[BaseModel], tool.metadata.fn_schema)
return cls(
name=tool.metadata.name,
description=tool.metadata.description,
args_schema=args_schema,
llama_index_tool=tool,
**kwargs,
)
@classmethod
def from_query_engine(
cls,
query_engine: Any,
name: str | None = None,
description: str | None = None,View on GitHub (pinned to 754d7323be)
Solutions
- Provide an explicit schema when building the llama-index tool: FunctionTool.from_defaults(fn=my_fn, fn_schema=MySchema) where MySchema is a pydantic BaseModel
- Set tool.metadata.fn_schema manually before calling from_tool if you control the metadata
- Upgrade llama-index so from_defaults reliably attaches DefaultToolFnSchema
Example fix
# before
from llama_index.core.tools import FunctionTool
t = FunctionTool.from_defaults(fn=lambda q: lookup(q)) # fn_schema may be None
crew_tool = LlamaIndexTool.from_tool(t) # ValueError
# after
from pydantic import BaseModel, Field
class LookupSchema(BaseModel):
query: str = Field(..., description="Query string")
t = FunctionTool.from_defaults(fn=lookup, fn_schema=LookupSchema)
crew_tool = LlamaIndexTool.from_tool(t) Defensive patterns
Strategy: validation
Validate before calling
def tool_has_fn_schema(tool) -> bool:
meta = getattr(tool, "metadata", None)
return getattr(meta, "fn_schema", None) is not None Type guard
def has_fn_schema(tool: Any) -> "TypeGuard[Any]":
return getattr(getattr(tool, "metadata", None), "fn_schema", None) is not None Try / catch
try:
crew_tool = LlamaIndexTool.from_tool(tool)
except ValueError as e:
if "fn_schema" in str(e):
from pydantic import BaseModel, Field
class Schema(BaseModel):
query: str = Field(...)
tool.metadata.fn_schema = Schema
crew_tool = LlamaIndexTool.from_tool(tool)
else:
raise Prevention
- Always build llama-index tools with an explicit fn_schema (pydantic BaseModel)
- Check tool.metadata.fn_schema before wrapping
- Write a unit test that wraps each llama-index tool you plan to expose to a crew
When it happens
Trigger: Calling from_tool on a BaseTool whose ToolMetadata was constructed without fn_schema; passing tools built by older llama-index factory methods that infer schemas lazily; passing a tool whose fn_schema is dynamically None (e.g. async tools without schema).
Common situations: Wrapping hand-written llama-index tools; llama-index version drift where from_defaults no longer auto-generates fn_schema for the object you hold; wrapping tools that only define metadata at call time.
Related errors
- Unable to read --definition path {definition_path}: {exc}
- Invalid data_type: '{raw_data_type}'. Valid values are: 'fil
- Directory does not exist: {source_ref}
- Website URL must be provided either during initialization or
- Expected a LlamaBaseTool, got {type(tool)}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/47132b3bb0a3a44b.
Report an issue: GitHub.