BerriAI/litellm · error · ValueError

TAVILY_API_KEY is not set. Set `TAVILY_API_KEY` environment

Error message

TAVILY_API_KEY is not set. Set `TAVILY_API_KEY` environment variable.

What it means

For Tavily web search, LiteLLM resolves the credential via resolve_server_api_key, checking the caller-supplied api_key and the TAVILY_API_KEY environment variable. If no key is found it raises this ValueError before any HTTP request is sent to Tavily. It is purely a credential-configuration failure.

Source

Thrown at litellm/llms/tavily/search/transformation.py:73

    def validate_environment(
        self,
        headers: dict,
        api_key: str | None = None,
        api_base: str | None = None,
        **kwargs,
    ) -> dict:
        """
        Validate environment and return headers.
        """
        api_key = self.resolve_server_api_key(
            caller_api_key=api_key,
            caller_api_base=api_base,
            key_env_vars=("TAVILY_API_KEY",),
            base_env_var="TAVILY_API_BASE",
            default_api_base=self.TAVILY_API_BASE,
        )
        if not api_key:
            raise ValueError("TAVILY_API_KEY is not set. Set `TAVILY_API_KEY` environment variable.")
        headers["Authorization"] = f"Bearer {api_key}"
        headers["Content-Type"] = "application/json"
        return headers

    def get_complete_url(
        self,
        api_base: str | None,
        optional_params: dict,
        data: dict | list[dict] | None = None,
        **kwargs,
    ) -> str:
        """
        Get complete URL for Search endpoint.
        """
        api_base = api_base or get_secret_str("TAVILY_API_BASE") or self.TAVILY_API_BASE

        # Append "/search" to the api base if it's not already there
        if not api_base.endswith("/search"):

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Export TAVILY_API_KEY=<key> in the runtime environment (get one at app.tavily.com).
  2. Pass api_key directly on the web-search call or set it in the proxy's model_list litellm_params.
  3. Verify visibility in the running process before retrying (e.g. print(os.environ.get('TAVILY_API_KEY'))).
  4. For the proxy, add the variable to the systemd unit / Docker Compose environment / .env loaded at startup.

Example fix

# before
results = litellm.web_search(query="latest rust release notes", provider="tavily")
# -> ValueError: TAVILY_API_KEY is not set...

# after
import os
results = litellm.web_search(
    query="latest rust release notes",
    provider="tavily",
    api_key=os.environ["TAVILY_API_KEY"],
)
Defensive patterns

Strategy: validation

Validate before calling

import os


def tavily_search_ready(api_key: str | None = None) -> bool:
    return bool(api_key or os.environ.get("TAVILY_API_KEY"))


if not tavily_search_ready():
    raise RuntimeError("TAVILY_API_KEY not configured — web search disabled")

Try / catch

try:
    results = litellm.web_search(query=q, provider="tavily")
except ValueError as e:
    if "TAVILY_API_KEY is not set" in str(e):
        # degrade gracefully: skip web search rather than fail the whole request
        results = []
    else:
        raise

Prevention

When it happens

Trigger: Calling litellm.web_search or the tavily provider with provider='tavily' when TAVILY_API_KEY is absent from the environment and no api_key was passed on the request or configured in proxy model settings.

Common situations: Enabling the web search tool in a new deployment without provisioning Tavily credentials; proxy environments where the env var must be set on the litellm proxy process; free-tier Tavily keys that were revoked and removed from the secrets store; scripts run under systemd/cron without EnvironmentFile.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18). Data as JSON: /api/errors/416170db9242beb0. Report an issue: GitHub.