crewAIInc/crewAI · error · ValueError

Tavily client is not initialized. Ensure 'tavily-python' is

Error message

Tavily client is not initialized. Ensure 'tavily-python' is installed and API key is set.

What it means

Raised by TavilyExtractorTool._run when self.client is None at call time. self.client is only built in __init__ when TAVILY_AVAILABLE is true; if construction took the install-prompt path (or the object was assembled unusually, e.g. via __new__ or failed init), _run refuses to call Tavily's extract API without a client.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/tavily_extractor_tool/tavily_extractor_tool.py:139

                raise ImportError(
                    "The 'tavily-python' package is required to use the TavilyExtractorTool. "
                    "Please install it with: uv add tavily-python"
                )

    def _run(
        self,
        urls: list[str] | str,
    ) -> str:
        """Synchronously extracts content from the given URL(s).

        Args:
            urls: The URL(s) to extract data from.

        Returns:
            A JSON string containing the extracted data.
        """
        if not self.client:
            raise ValueError(
                "Tavily client is not initialized. Ensure 'tavily-python' is installed and API key is set."
            )

        return json.dumps(
            self.client.extract(
                urls=urls,
                extract_depth=self.extract_depth,
                include_images=self.include_images,
                timeout=self.timeout,
            ),
            indent=2,
        )

    async def _arun(
        self,
        urls: list[str] | str,
    ) -> str:
        """Asynchronously extracts content from the given URL(s).

View on GitHub (pinned to 754d7323be)

Solutions

  1. Install tavily-python and create a NEW TavilyExtractorTool instance (the old one will never gain a client).
  2. Verify TAVILY_API_KEY / the api_key argument is set at construction time.
  3. Check tool.client is truthy before invoking run(); treat None as 'rebuild the tool'.

Example fix

# before
result = tool._run("https://example.com")  # client is None -> ValueError

# after
if not tool.client:
    tool = TavilyExtractorTool(api_key=...)  # rebuild after installing tavily-python
result = tool._run("https://example.com")
Defensive patterns

Strategy: type-guard

Validate before calling

if not getattr(tool, "client", None):
    raise RuntimeError("TavilyExtractorTool has no client; re-create it after installing tavily-python")

Type guard

def extractor_ready(tool) -> bool:
    """True when the sync Tavily client is initialized."""
    return getattr(tool, "client", None) is not None

Try / catch

try:
    out = tool._run(urls)
except ValueError as e:
    if "Tavily client is not initialized" in str(e):
        tool = TavilyExtractorTool(api_key=os.environ["TAVILY_API_KEY"])
        out = tool._run(urls)
    else:
        raise

Prevention

When it happens

Trigger: Calling tool._run(urls) (or tool.run) on a TavilyExtractorTool whose __init__ never set self.client — i.e. tavily-python was not importable at construction time, or TAVILY_API_KEY-dependent client creation was skipped.

Common situations: Tool object created before tavily-python was installed (client stayed None) and then used after install without re-instantiation; partial init where an exception in __init__ left the object half-configured.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/52400fa714e67005. Report an issue: GitHub.