{"record":{"id":"c5322c91827bb357","repo":"BerriAI/litellm","slug":"google-pse-api-key-is-not-set-set-google-pse-api","errorCode":null,"errorMessage":"GOOGLE_PSE_API_KEY is not set. Set `GOOGLE_PSE_API_KEY` environment variable.","messagePattern":"GOOGLE_PSE_API_KEY is not set\\. Set `GOOGLE_PSE_API_KEY` environment variable\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/google_pse/search/transformation.py","lineNumber":92,"sourceCode":"        api_key: str | None = None,\n        api_base: str | None = None,\n        **kwargs,\n    ) -> dict:\n        \"\"\"\n        Validate environment and return headers.\n\n        Google PSE uses API key as a query parameter, not in headers.\n        This method is called but headers are not used for authentication.\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=(\"GOOGLE_PSE_API_KEY\",),\n            base_env_var=\"GOOGLE_PSE_API_BASE\",\n            default_api_base=self.GOOGLE_PSE_API_BASE,\n        )\n        if not api_key:\n            raise ValueError(\"GOOGLE_PSE_API_KEY is not set. Set `GOOGLE_PSE_API_KEY` environment variable.\")\n\n        # Also check for search engine ID\n        search_engine_id: Final = kwargs.get(\"search_engine_id\") or get_secret_str(\"GOOGLE_PSE_ENGINE_ID\")\n        if not search_engine_id:\n            raise ValueError(\n                \"GOOGLE_PSE_ENGINE_ID is not set. Set `GOOGLE_PSE_ENGINE_ID` environment variable or pass `search_engine_id` parameter.\"\n            )\n\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:","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/google_pse/search/transformation.py#L74-L110","documentation":"Raised by the Google PSE (Programmable Search Engine) search provider during header setup when resolve_server_api_key cannot find a key: no caller api_key was passed, no GOOGLE_PSE_API_KEY env var is set (or it's empty), and no key source matched. Note the provider resolves the key host-aware against GOOGLE_PSE_API_BASE to avoid leaking a server-managed key to a caller-supplied host, so a mismatched api_base can also suppress key resolution.","triggerScenarios":"Invoking litellm's web search with provider google_pse without passing api_key and without GOOGLE_PSE_API_KEY exported — e.g. calling the search transformation's set_headers path (or a higher-level search API that reaches it) in a fresh shell, CI runner, or container where only other provider keys are configured. Also fires when GOOGLE_PSE_API_BASE is set to a host that is not authorized for the server key.","commonSituations":".env files loaded for the LLM provider but not for search settings; deploying search features to environments where the Google Cloud key was never provisioned; passing api_base without a matching api_key so the host-aware resolver declines to reuse the server key.","solutions":["Export GOOGLE_PSE_API_KEY with a valid Google API key (created in Google Cloud Console -> Credentials, with Custom Search API enabled).","Or pass api_key explicitly on the search call if per-request keys are preferred.","If GOOGLE_PSE_API_BASE is set, ensure it is either the default (https://www.googleapis.com) or a host the server key may be sent to; remove a stray GOOGLE_PSE_API_BASE otherwise.","Verify the key is non-empty: many secret managers inject empty strings that resolve as missing."],"exampleFix":"# before: no key configured\nos.environ.pop(\"GOOGLE_PSE_API_KEY\", None)\nresults = litellm.web_search(provider=\"google_pse\", query=\"hello\")  # ValueError\n\n# after: provision and export the key\nos.environ[\"GOOGLE_PSE_API_KEY\"] = \"AIza...\"\nos.environ[\"GOOGLE_PSE_ENGINE_ID\"] = \"a1b2c3d4e5f6g7h8j\"\nresults = litellm.web_search(provider=\"google_pse\", query=\"hello\")","handlingStrategy":"validation","validationCode":"import os\n\nmissing = [v for v in (\"GOOGLE_PSE_API_KEY\", \"GOOGLE_PSE_ENGINE_ID\") if not os.getenv(v)]\nif missing:\n    raise RuntimeError(f\"google_pse misconfigured; missing env vars: {', '.join(missing)}\")","typeGuard":"def google_pse_configured() -> bool:\n    \"\"\"True when both the API key and engine ID resolve for google_pse search.\"\"\"\n    import os\n    return bool(os.getenv(\"GOOGLE_PSE_API_KEY\")) and bool(os.getenv(\"GOOGLE_PSE_ENGINE_ID\"))","tryCatchPattern":"try:\n    results = litellm.web_search(provider=\"google_pse\", query=q)\nexcept ValueError as e:\n    if \"GOOGLE_PSE_API_KEY is not set\" in str(e):\n        raise RuntimeError(\"Provision a Google Cloud API key (Custom Search API enabled) as GOOGLE_PSE_API_KEY\") from e\n    raise","preventionTips":["Add both GOOGLE_PSE_* env vars to the deployment secrets checklist.","Assert config at startup, not per request.","Enable the Custom Search API on the key's Google Cloud project.","If using a custom api_base, set GOOGLE_PSE_API_BASE so host-aware key resolution succeeds."],"tags":["google-pse","search","api-key","configuration","environment"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}