{"record":{"id":"8e4e2751cd6f9fb5","repo":"crewAIInc/crewAI","slug":"client-not-initialized","errorCode":null,"errorMessage":"Client not initialized","messagePattern":"Client not initialized","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/exa_tools/exa_search_tool.py","lineNumber":132,"sourceCode":"            client_kwargs[\"api_key\"] = self.api_key\n        if self.base_url:\n            client_kwargs[\"base_url\"] = self.base_url\n        self.client = Exa(**client_kwargs)\n        self.client.headers[\"x-exa-integration\"] = \"crewai\"\n        self.content = content\n        self.summary = summary\n        self.highlights = highlights\n        self.type = type\n\n    def _run(\n        self,\n        search_query: str,\n        start_published_date: str | None = None,\n        end_published_date: str | None = None,\n        include_domains: list[str] | None = None,\n    ) -> Any:\n        if self.client is None:\n            raise ValueError(\"Client not initialized\")\n\n        search_params: SearchParams = {\n            \"type\": self.type,\n        }\n\n        if start_published_date:\n            search_params[\"start_published_date\"] = start_published_date\n        if end_published_date:\n            search_params[\"end_published_date\"] = end_published_date\n        if include_domains:\n            search_params[\"include_domains\"] = include_domains\n\n        contents_kwargs: dict[str, Any] = {}\n        if self.content:\n            contents_kwargs[\"text\"] = self.content\n        if self.highlights:\n            contents_kwargs[\"highlights\"] = self.highlights\n        if self.summary:","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/exa_tools/exa_search_tool.py#L114-L150","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ntool = ExaSearchTool.__new__(ExaSearchTool)\ntool._run('query')  # ValueError\n\n# after\ntool = ExaSearchTool(api_key=EXA_API_KEY)\ntool._run('query')","handlingStrategy":"type-guard","validationCode":"if getattr(tool, 'client', None) is None:\n    raise RuntimeError('ExaSearchTool built without a client; re-run its __init__')","typeGuard":"def has_exa_client(tool: 'ExaSearchTool') -> bool:\n    return getattr(tool, 'client', None) is not None","tryCatchPattern":"try:\n    results = tool._run('query')\nexcept ValueError as e:\n    if 'Client not initialized' in str(e):\n        tool = ExaSearchTool(api_key=KEY)  # rebuild properly\n        results = tool._run('query')\n    else:\n        raise","preventionTips":["Always instantiate via the constructor, never __new__/model_copy for runnable tools.","In tests, inject a mock client instead of leaving the attribute None."],"tags":["exa","initialization","defensive-check","tool-args"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}