BerriAI/litellm · error · GeminiError

raw_response.text

Error message

raw_response.text

What it means

Raised in GoogleAIStudioInteractionsConfig.transform_response when the response body cannot be processed: it first calls logging_obj.post_call with raw_response.text, then raw_response.json(). Any exception there (non-JSON body such as an HTML gateway error, an empty 5xx body, malformed JSON) triggers a GeminiError whose message is the VERBATIM response text, with the upstream status_code and headers attached. The odd message you see is simply the raw upstream payload.

Source

Thrown at litellm/llms/gemini/interactions/transformation.py:244

                        request_body["response_format"] = [existing_rf, image_rf]

        return request_body

    def transform_response(
        self,
        model: str | None,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
    ) -> InteractionsAPIResponse:
        """Parse response - it already matches our response type."""
        try:
            logging_obj.post_call(
                original_response=raw_response.text,
                additional_args={"complete_input_dict": {}},
            )
            raw_json: Final = raw_response.json()
        except Exception:
            raise GeminiError(
                message=raw_response.text,
                status_code=raw_response.status_code,
                headers=dict(raw_response.headers),
            )

        verbose_logger.debug("Google AI Interactions response: %s", raw_json)

        response: Final = InteractionsAPIResponse(**raw_json)
        response._hidden_params["headers"] = dict(raw_response.headers)
        response._hidden_params["additional_headers"] = process_response_headers(dict(raw_response.headers))

        return response

    def transform_streaming_response(
        self,
        model: str | None,
        parsed_chunk: dict,
        logging_obj: LiteLLMLoggingObj,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Read the GeminiError: message carries the raw upstream body, status_code and headers tell you who rejected it (502/504 → gateway; 429 → quota; 403 → access)
  2. If message contains HTML, inspect it for the proxy product name and fix/bypass the proxy for generativelanguage.googleapis.com
  3. For streaming requests, use the streaming code path (stream=True) so SSE bodies are parsed correctly
  4. Retry transient 5xxs with backoff; make retries idempotent using previous_interaction_id where appropriate

Example fix

# before
resp = litellm.interactions.create(model='gemini-2.5-flash', input=..., api_key=KEY)
# GeminiError: <html><head><title>502 Bad Gateway</title>...

# after - surface status and detect proxy HTML instead of crashing on the raw text
from litellm.llms.gemini.common_utils import GeminiError
try:
    resp = litellm.interactions.create(model='gemini-2.5-flash', input=..., api_key=KEY)
except GeminiError as e:
    if e.status_code in (502, 503, 504) or '<html' in (e.message or '').lower():
        raise RuntimeError(f'Gateway error {e.status_code}, check api_base/proxy') from e
    raise
Defensive patterns

Strategy: try-catch

Try / catch

from litellm.llms.gemini.common_utils import GeminiError

try:
    resp = litellm.interactions.create(model='gemini-2.5-flash', input=inp, api_key=KEY)
except GeminiError as e:
    if e.status_code and e.status_code >= 500 or '<html' in (e.message or '').lower():
        backoff_and_retry()  # gateway/transient — safe to retry
    else:
        raise  # 4xx: fix key/model/api_base; message holds the raw upstream body

Prevention

When it happens

Trigger: A proxy/gateway (custom api_base) returning HTML 502/504 pages; Cloudflare challenge/block pages; an empty body on a server error; region or model-access denials returning non-JSON; a streaming (?alt=sse) response being parsed by the non-streaming transform.

Common situations: Self-hosted LiteLLM proxy fronts Google with an LB that errors in HTML; corporate proxies injecting block pages; transient Google 5xxs; accidentally calling the non-streaming completion path with stream=True data.

Related errors


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