BerriAI/litellm · error · ValueError

usageMetadata not found in completion_response. Got={complet

Error message

usageMetadata not found in completion_response. Got={completion_response}

What it means

Gemini response guard: the completion_response JSON has candidates but no usageMetadata block, so token usage cannot be extracted; the full response is echoed to aid debugging of the unexpected payload shape.

Source

Thrown at litellm/llms/vertex_ai/gemini/vertex_and_google_ai_studio_gemini.py:1743

        URL context also emits groundingMetadata (with groundingChunks but no webSearchQueries),
        so presence of groundingMetadata alone is not a sufficient signal.
        See https://ai.google.dev/gemini-api/docs/pricing and
        https://github.com/BerriAI/litellm/discussions/33198
        """
        if "candidates" not in completion_response:
            return False
        for candidate in completion_response["candidates"] or []:
            grounding_metadata, _, _, _ = VertexGeminiConfig._extract_candidate_metadata(candidate)
            if VertexGeminiConfig._calculate_web_search_requests(grounding_metadata):
                return True
        return False

    @staticmethod
    def _calculate_usage(
        completion_response: GenerateContentResponseBody | BidiGenerateContentServerMessage,
    ) -> Usage:
        if completion_response is not None and "usageMetadata" not in completion_response:
            raise ValueError(f"usageMetadata not found in completion_response. Got={completion_response}")
        cached_tokens: int | None = None
        # Separate variables for prompt tokens by modality
        prompt_audio_tokens: int | None = None
        prompt_image_tokens: int | None = None
        prompt_text_tokens: int | None = None
        prompt_video_tokens: int | None = None
        prompt_tokens_details: PromptTokensDetailsWrapper | None = None
        reasoning_tokens: int | None = None
        response_tokens: int | None = None
        response_tokens_details: CompletionTokensDetailsWrapper | None = None
        usage_metadata: Final = completion_response["usageMetadata"]

        def _get_token_count(detail: Mapping[str, object]) -> int:
            raw_token_count: Final = detail.get("tokenCount", detail.get("token_count", 0))
            return raw_token_count if isinstance(raw_token_count, int) else 0

        if "cachedContentTokenCount" in usage_metadata:
            cached_tokens = usage_metadata["cachedContentTokenCount"]

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. The completion response lacked usageMetadata; inspect the raw completion_response.
  2. Report to litellm if the Vertex response schema changed.

Example fix

# log completion_response to inspect the returned payload.
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Triggered when the Gemini completion response lacks usageMetadata.

Common situations: See trigger scenarios.


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