BerriAI/litellm · critical · ValueError

api_key is required

Error message

api_key is required

What it means

In get_complete_url(), after api_base resolves, the Gemini Files config resolves the key from three sources in order: the explicit api_key argument, litellm_params['api_key'], then self.get_api_key() (GOOGLE_API_KEY/GEMINI_API_KEY env). If all three are empty it raises 'api_key is required' — the URL for the upload would otherwise be built with no way to authenticate it.

Source

Thrown at litellm/llms/gemini/files/transformation.py:87

        litellm_params: dict,
        stream: bool | None = None,
    ) -> str:
        """
        OPTIONAL

        Get the complete url for the request

        Some providers need `model` in `api_base`
        """
        endpoint: Final = "upload/v1beta/files"
        api_base = self.get_api_base(api_base)
        if not api_base:
            raise ValueError("api_base is required")

        # Get API key from multiple sources
        final_api_key: Final = api_key or litellm_params.get("api_key") or self.get_api_key()
        if not final_api_key:
            raise ValueError("api_key is required")

        url: Final = f"{api_base}/{endpoint}"
        return url

    def get_supported_openai_params(self, model: str) -> list[OpenAICreateFileRequestOptionalParams]:
        return []

    def map_openai_params(
        self,
        non_default_params: dict,
        optional_params: dict,
        model: str,
        drop_params: bool,
    ) -> dict:
        return optional_params

    def transform_create_file_request(
        self,

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Set GOOGLE_API_KEY (or GEMINI_API_KEY) before the file call.
  2. Or pass api_key in litellm_params on the request so the third fallback succeeds.
  3. Distinguish from Vertex: gemini/ file operations want an AI Studio API key, not a service-account JSON.

Example fix

# before
litellm.create_file(model="gemini/", file=f)  # no key anywhere -> ValueError

# after
litellm.create_file(model="gemini/", file=f, litellm_params={"api_key": "AIza..."})
Defensive patterns

Strategy: validation

Validate before calling

import os

def gemini_files_key(litellm_params: dict | None = None) -> str:
    key = (
        (litellm_params or {}).get("api_key")
        or os.getenv("GOOGLE_API_KEY")
        or os.getenv("GEMINI_API_KEY")
    )
    if not key:
        raise RuntimeError("Gemini file operations need an API key")
    return key

Try / catch

try:
    litellm.create_file(model="gemini/", file=f, purpose="user_data")
except ValueError as e:
    if "api_key is required" in str(e):
        raise RuntimeError("Missing Gemini key for file upload") from e
    raise

Prevention

When it happens

Trigger: Gemini file upload/download where neither the call nor the environment supplies a key: no api_key argument, no api_key in litellm_params, and GOOGLE_API_KEY/GEMINI_API_KEY unset.

Common situations: Same deployment gaps as other key errors: credentials loaded after import, missing in containers, or the file-upload feature added to a service that only configured a Vertex service account (not an AI Studio API key).

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/e828a041bb7b379c. Report an issue: GitHub.