{"record":{"id":"833b347062a93cff","repo":"crewAIInc/crewAI","slug":"you-are-missing-the-exa-py-package-please-insta","errorCode":null,"errorMessage":"You are missing the 'exa_py' package. Please install it to use ExaSearchTool.","messagePattern":"You are missing the 'exa_py' package\\. Please install it to use ExaSearchTool\\.","errorType":"exception","errorClass":"ImportError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/exa_tools/exa_search_tool.py","lineNumber":108,"sourceCode":"        super().__init__(\n            **kwargs,\n        )\n        global Exa\n        if Exa is None:\n            import click\n\n            if click.confirm(\n                \"You are missing the 'exa_py' package. Would you like to install it?\"\n            ):\n                import subprocess\n\n                subprocess.run([\"uv\", \"add\", \"exa_py\"], check=True)  # noqa: S607\n\n                from exa_py import Exa as _Exa\n\n                Exa = _Exa  # type: ignore[misc]\n            else:\n                raise ImportError(\n                    \"You are missing the 'exa_py' package. Please install it to use ExaSearchTool.\"\n                )\n\n        client_kwargs: dict[str, str] = {}\n        if self.api_key:\n            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,","sourceCodeStart":90,"sourceCodeEnd":126,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/exa_tools/exa_search_tool.py#L90-L126","documentation":"Raised by ExaSearchTool.__init__ when the 'exa_py' package is missing AND the user declined the interactive install prompt (click.confirm returned False). The tool tries to auto-install via 'uv add exa_py'; if you answer 'no' (or no TTY makes the confirm fail/decline), this ImportError is raised.","triggerScenarios":"Instantiating ExaSearchTool without exa_py installed, then answering 'n' to the 'Would you like to install it?' prompt; running in a non-interactive context where click.confirm cannot prompt (it raises Abort, or defaults to declining).","commonSituations":"CI pipelines or containers hitting the interactive prompt with no TTY; a teammate's fresh clone without the optional dependency; mistakenly expecting silent auto-install.","solutions":["Install it directly: uv add exa_py (or pip install exa_py), then retry.","For CI/non-interactive runs, pre-install exa_py in the image or requirements so the prompt never appears.","Alternatively, answer 'y' to the prompt in an interactive session and let the tool install it."],"exampleFix":"# before: declines prompt -> ImportError\n# after: shell\n#   uv add exa_py\ntool = ExaSearchTool(api_key=EXA_API_KEY)","handlingStrategy":"try-catch","validationCode":"def exa_available() -> bool:\n    try:\n        import exa_py  # noqa: F401\n        return True\n    except ImportError:\n        return False","typeGuard":null,"tryCatchPattern":"try:\n    tool = ExaSearchTool(api_key=KEY)\nexcept ImportError as e:\n    if 'exa_py' in str(e):\n        raise SystemExit('Run: pip install exa_py') from e\n    raise","preventionTips":["Pre-install exa_py in CI images so the click.confirm prompt never blocks a non-TTY run.","Set CI env var / use click's non-interactive behavior awareness: auto-install deps before instantiating tools."],"tags":["exa","import-error","dependency","interactive-prompt","optional-deps"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}