crewAIInc/crewAI · error · ValueError
Client not initialized
Error message
Client not initialized
What it means
Defensive guard in ExaSearchTool._run: it refuses to execute a search when self.client is None. Under normal initialization __init__ always assigns self.client, so hitting this means the tool was constructed through an unusual path where the Exa client was never created (e.g. subclass bypassing __init__, or a failed/partial init left the attribute at its default).
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/exa_tools/exa_search_tool.py:132
client_kwargs["api_key"] = self.api_key
if self.base_url:
client_kwargs["base_url"] = self.base_url
self.client = Exa(**client_kwargs)
self.client.headers["x-exa-integration"] = "crewai"
self.content = content
self.summary = summary
self.highlights = highlights
self.type = type
def _run(
self,
search_query: str,
start_published_date: str | None = None,
end_published_date: str | None = None,
include_domains: list[str] | None = None,
) -> Any:
if self.client is None:
raise ValueError("Client not initialized")
search_params: SearchParams = {
"type": self.type,
}
if start_published_date:
search_params["start_published_date"] = start_published_date
if end_published_date:
search_params["end_published_date"] = end_published_date
if include_domains:
search_params["include_domains"] = include_domains
contents_kwargs: dict[str, Any] = {}
if self.content:
contents_kwargs["text"] = self.content
if self.highlights:
contents_kwargs["highlights"] = self.highlights
if self.summary:View on GitHub (pinned to 754d7323be)
Solutions
- Construct the tool normally: ExaSearchTool(api_key=...) so __init__ builds self.client.
- If subclassing, call super().__init__(...) so the client is initialized.
- In tests, set tool.client to a mock Exa instance rather than leaving it None.
Example fix
# before
tool = ExaSearchTool.__new__(ExaSearchTool)
tool._run('query') # ValueError
# after
tool = ExaSearchTool(api_key=EXA_API_KEY)
tool._run('query') Defensive patterns
Strategy: type-guard
Validate before calling
if getattr(tool, 'client', None) is None:
raise RuntimeError('ExaSearchTool built without a client; re-run its __init__') Type guard
def has_exa_client(tool: 'ExaSearchTool') -> bool:
return getattr(tool, 'client', None) is not None Try / catch
try:
results = tool._run('query')
except ValueError as e:
if 'Client not initialized' in str(e):
tool = ExaSearchTool(api_key=KEY) # rebuild properly
results = tool._run('query')
else:
raise Prevention
- Always instantiate via the constructor, never __new__/model_copy for runnable tools.
- In tests, inject a mock client instead of leaving the attribute None.
When it happens
Trigger: Calling tool._run(...) on an ExaSearchTool instance whose __init__ did not complete the client assignment — e.g. object created via __new__ / model validation tricks, a subclass overriding __init__ without calling super, or monkeypatched/partially-mocked construction in tests.
Common situations: Unit tests constructing the tool with mocks that skip client setup; Pydantic model_copy/reconstruct paths that skip __init__; tampering with tool internals before running.
Related errors
- FirecrawlApp not properly initialized
- FirecrawlApp not properly initialized
- FirecrawlApp not properly initialized
- Client is not initialized
- Failed to initialize MCP Adapter: {e}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/8e4e2751cd6f9fb5.
Report an issue: GitHub.