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
- 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)
- If message contains HTML, inspect it for the proxy product name and fix/bypass the proxy for generativelanguage.googleapis.com
- For streaming requests, use the streaming code path (stream=True) so SSE bodies are parsed correctly
- 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
- Treat an HTML message as a proxy/gateway fault: check api_base routing before blaming Google
- Retry 5xx GeminiErrors with exponential backoff; do not retry 4xx
- Use the streaming path for stream=True so SSE bodies never hit the JSON parser
- Alert on status_code + headers from GeminiError — they identify the rejecting layer
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
- Error parsing file upload response: {e}
- Error parsing file retrieve response: {e}
- Error parsing file delete response: {e}
- Google API key is required. Set GOOGLE_API_KEY or GEMINI_API
- Either 'model' or 'agent' must be provided
AI-assisted analysis of BerriAI/litellm@77b7c6c40c (2026-08-18).
Data as JSON: /api/errors/348ec733693cb1f0.
Report an issue: GitHub.