{"record":{"id":"2be7f7b3d727b4b8","repo":"BerriAI/litellm","slug":"gemini-api-key-or-google-api-key-is-required","errorCode":null,"errorMessage":"GEMINI_API_KEY or GOOGLE_API_KEY is required","messagePattern":"GEMINI_API_KEY or GOOGLE_API_KEY is required","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/gemini/vector_stores/transformation.py","lineNumber":132,"sourceCode":"    ) -> tuple[str, dict]:\n        \"\"\"\n        Transform search request to Gemini's generateContent format.\n\n        Gemini File Search works by calling generateContent with a file_search tool.\n        \"\"\"\n        # Convert query list to single string if needed\n        if isinstance(query, list):\n            query = \" \".join(query)\n\n        # Get model from litellm_params or use default\n        # Note: File Search requires gemini-2.5-flash or later\n        model = litellm_params.get(\"model\") or \"gemini-2.5-flash\"\n        if model and model.startswith(\"gemini/\"):\n            model = model.replace(\"gemini/\", \"\")\n\n        api_key: Final = litellm_params.get(\"api_key\") or GeminiModelInfo.get_api_key()\n        if not api_key:\n            raise ValueError(\"GEMINI_API_KEY or GOOGLE_API_KEY is required\")\n        url: Final = f\"{api_base}/models/{model}:generateContent\"\n\n        # Build file_search tool configuration (using snake_case as per Gemini docs)\n        file_search_config: Final[dict[str, Any]] = {\"file_search_store_names\": [vector_store_id]}\n\n        # Add metadata filter if provided\n        metadata_filter: Final = vector_store_search_optional_params.get(\"filters\")\n        if metadata_filter:\n            # Convert to Gemini filter syntax if it's a dict\n            if isinstance(metadata_filter, dict):\n                # Simple conversion - may need more sophisticated mapping\n                filter_parts: Final = []\n                for key, value in metadata_filter.items():\n                    if isinstance(value, str):\n                        filter_parts.append(f'{key} = \"{value}\"')\n                    else:\n                        filter_parts.append(f\"{key} = {value}\")\n                file_search_config[\"metadata_filter\"] = \" AND \".join(filter_parts)","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/gemini/vector_stores/transformation.py#L114-L150","documentation":"Raised in the Gemini vector-store search request transform when no API key is found: it checks litellm_params['api_key'] then falls back to GeminiModelInfo.get_api_key() (GEMINI_API_KEY / GOOGLE_API_KEY env). File Search grounds generateContent calls against a file search store, which requires a Google API key, so the request is aborted with ValueError.","triggerScenarios":"Calling litellm.vector_store_search (Gemini File Search) with model gemini-2.5-flash and no api_key in litellm_params while GEMINI_API_KEY/GOOGLE_API_KEY are unset in the environment.","commonSituations":"Env vars configured for the LLM proxy but not the worker doing file search; key rotation leaving stale empty-string env values; CI pipelines lacking secrets.","solutions":["Pass api_key in litellm_params: {'api_key': 'AIza...'} on the search call.","Export GEMINI_API_KEY or GOOGLE_API_KEY in the calling process.","Ensure the value is non-empty (an empty string also fails the truthiness check)."],"exampleFix":"# before\nresults = litellm.vector_store_search(vector_store_id=vs_id, query='hello', litellm_params={'model': 'gemini-2.5-flash'})\n\n# after\nimport os\nresults = litellm.vector_store_search(\n    vector_store_id=vs_id,\n    query='hello',\n    litellm_params={'model': 'gemini-2.5-flash', 'api_key': os.environ['GEMINI_API_KEY']},\n)\n","handlingStrategy":"validation","validationCode":"import os\n\ndef has_gemini_key(litellm_params=None) -> bool:\n    return bool(\n        (litellm_params or {}).get(\"api_key\")\n        or os.environ.get(\"GEMINI_API_KEY\")\n        or os.environ.get(\"GOOGLE_API_KEY\")\n    )\n\nif not has_gemini_key(params):\n    raise ConfigError(\"Gemini key required for File Search\")","typeGuard":null,"tryCatchPattern":"try:\n    results = litellm.vector_store_search(vector_store_id=vs, query=q, litellm_params=params)\nexcept ValueError as e:\n    if \"GEMINI_API_KEY or GOOGLE_API_KEY is required\" in str(e):\n        raise ConfigError(\"Missing Gemini key for File Search\") from e\n    raise","preventionTips":["Pass api_key in litellm_params on every file-search call rather than trusting env.","Check env keys are set AND non-empty at service startup.","Use the same key-resolution check across chat and file-search paths."],"tags":["auth","gemini","vector-stores","api-key","file-search"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}