crewAIInc/crewAI · error · ValueError
Expected a BaseQueryEngine, got {type(query_engine)}
Error message
Expected a BaseQueryEngine, got {type(query_engine)} What it means
LlamaIndexTool.from_query_engine type-checks its first argument against llama_index.core.query_engine.BaseQueryEngine. Passing a raw index (VectorStoreIndex), a retriever, or an object from a mismatched llama-index version fails, since the wrapper immediately feeds the object into QueryEngineTool.from_defaults which needs a real query engine.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/llamaindex_tool/llamaindex_tool.py:65
**kwargs,
)
@classmethod
def from_query_engine(
cls,
query_engine: Any,
name: str | None = None,
description: str | None = None,
return_direct: bool = False,
**kwargs: Any,
) -> LlamaIndexTool:
from llama_index.core.query_engine import ( # type: ignore[import-not-found]
BaseQueryEngine,
)
from llama_index.core.tools import QueryEngineTool
if not isinstance(query_engine, BaseQueryEngine):
raise ValueError(f"Expected a BaseQueryEngine, got {type(query_engine)}")
# NOTE: by default the schema expects an `input` variable. However this
# confuses crewAI so we are renaming to `query`.
class QueryToolSchema(BaseModel):
"""Schema for query tool."""
query: str = Field(..., description="Search query for the query tool.")
# NOTE: setting `resolve_input_errors` to True is important because the schema expects `input` but we are using `query`
query_engine_tool = QueryEngineTool.from_defaults(
query_engine,
name=name,
description=description,
return_direct=return_direct,
resolve_input_errors=True,
)
# HACK: we are replacing the schema with our custom schema
query_engine_tool.metadata.fn_schema = QueryToolSchemaView on GitHub (pinned to 754d7323be)
Solutions
- Convert the index first: LlamaIndexTool.from_query_engine(index.as_query_engine(), name=..., description=...)
- Upgrade llama-index to a version with llama_index.core (>=0.10) to match crewai-tools' expectations
- Verify a single llama-index install: pip list | grep llama-index
Example fix
# before
index = VectorStoreIndex.from_documents(docs)
tool = LlamaIndexTool.from_query_engine(index) # ValueError
# after
tool = LlamaIndexTool.from_query_engine(
index.as_query_engine(),
name="doc_qa",
description="Answer questions about the docs",
) Defensive patterns
Strategy: type-guard
Validate before calling
def is_query_engine(obj) -> bool:
from llama_index.core.query_engine import BaseQueryEngine
return isinstance(obj, BaseQueryEngine) Type guard
from typing import Any, TypeGuard
def is_query_engine(obj: Any) -> TypeGuard[Any]:
try:
from llama_index.core.query_engine import BaseQueryEngine
except ImportError:
return False
return isinstance(obj, BaseQueryEngine) Try / catch
try:
tool = LlamaIndexTool.from_query_engine(engine)
except ValueError as e:
if "Expected a BaseQueryEngine" in str(e):
tool = LlamaIndexTool.from_query_engine(engine.as_query_engine())
else:
raise Prevention
- Always call index.as_query_engine() before from_query_engine
- Standardize on llama-index >= 0.10 module layout
- Write a small adapter that accepts index-or-engine and normalizes it
When it happens
Trigger: Calling from_query_engine(VectorStoreIndex(...)) instead of index.as_query_engine(); passing a RetrieverQueryEngine from a different llama-index install; legacy llama-index <=0.9 code where the module path is llama_index.core vs llama_index.
Common situations: Following older tutorials that passed indexes directly; forgetting the .as_query_engine() step; duplicate llama-index packages breaking isinstance.
Related errors
- Expected a LlamaBaseTool, got {type(tool)}
- The LlamaIndex tool does not have an fn_schema specified.
- Client is not initialized
- Invalid data_type: '{raw_data_type}'. Valid values are: 'fil
- File does not exist: {source_ref}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/136abf05100ac97a.
Report an issue: GitHub.