{"record":{"id":"416170db9242beb0","repo":"BerriAI/litellm","slug":"tavily-api-key-is-not-set-set-tavily-api-key-en","errorCode":null,"errorMessage":"TAVILY_API_KEY is not set. Set `TAVILY_API_KEY` environment variable.","messagePattern":"TAVILY_API_KEY is not set\\. Set `TAVILY_API_KEY` environment variable\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/tavily/search/transformation.py","lineNumber":73,"sourceCode":"    def validate_environment(\n        self,\n        headers: dict,\n        api_key: str | None = None,\n        api_base: str | None = None,\n        **kwargs,\n    ) -> dict:\n        \"\"\"\n        Validate environment and return headers.\n        \"\"\"\n        api_key = self.resolve_server_api_key(\n            caller_api_key=api_key,\n            caller_api_base=api_base,\n            key_env_vars=(\"TAVILY_API_KEY\",),\n            base_env_var=\"TAVILY_API_BASE\",\n            default_api_base=self.TAVILY_API_BASE,\n        )\n        if not api_key:\n            raise ValueError(\"TAVILY_API_KEY is not set. Set `TAVILY_API_KEY` environment variable.\")\n        headers[\"Authorization\"] = f\"Bearer {api_key}\"\n        headers[\"Content-Type\"] = \"application/json\"\n        return headers\n\n    def get_complete_url(\n        self,\n        api_base: str | None,\n        optional_params: dict,\n        data: dict | list[dict] | None = None,\n        **kwargs,\n    ) -> str:\n        \"\"\"\n        Get complete URL for Search endpoint.\n        \"\"\"\n        api_base = api_base or get_secret_str(\"TAVILY_API_BASE\") or self.TAVILY_API_BASE\n\n        # Append \"/search\" to the api base if it's not already there\n        if not api_base.endswith(\"/search\"):","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/BerriAI/litellm/blob/77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8/litellm/llms/tavily/search/transformation.py#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Export TAVILY_API_KEY=<key> in the runtime environment (get one at app.tavily.com).","Pass api_key directly on the web-search call or set it in the proxy's model_list litellm_params.","Verify visibility in the running process before retrying (e.g. print(os.environ.get('TAVILY_API_KEY'))).","For the proxy, add the variable to the systemd unit / Docker Compose environment / .env loaded at startup."],"exampleFix":"# before\nresults = litellm.web_search(query=\"latest rust release notes\", provider=\"tavily\")\n# -> ValueError: TAVILY_API_KEY is not set...\n\n# after\nimport os\nresults = litellm.web_search(\n    query=\"latest rust release notes\",\n    provider=\"tavily\",\n    api_key=os.environ[\"TAVILY_API_KEY\"],\n)","handlingStrategy":"validation","validationCode":"import os\n\n\ndef tavily_search_ready(api_key: str | None = None) -> bool:\n    return bool(api_key or os.environ.get(\"TAVILY_API_KEY\"))\n\n\nif not tavily_search_ready():\n    raise RuntimeError(\"TAVILY_API_KEY not configured — web search disabled\")","typeGuard":null,"tryCatchPattern":"try:\n    results = litellm.web_search(query=q, provider=\"tavily\")\nexcept ValueError as e:\n    if \"TAVILY_API_KEY is not set\" in str(e):\n        # degrade gracefully: skip web search rather than fail the whole request\n        results = []\n    else:\n        raise","preventionTips":["Gate optional tools (web search) behind credential checks so missing keys degrade features, not requests.","Keep provider env vars in one declarative list validated at boot.","For litellm proxy, put TAVILY_API_KEY in the proxy process environment and document it in deployment config."],"tags":["tavily","web-search","api-key","environment-variables","litellm"],"backgroundTag":"missing-api-key","analyzedSha":"77b7c6c40c0c5aa5fbcb1d6a1825ac39ca8829b8","analyzedAt":"2026-08-18T11:44:31.656Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}