BerriAI/litellm · error · ValueError

Failed to parse operation response: {e}

Error message

Failed to parse operation response: {e}

What it means

Raised while handling a Veo long-running-operation response: the raw JSON is validated against the GeminiLongRunningOperationResponse Pydantic model, and any ValidationError is re-raised as ValueError('Failed to parse operation response: ...'). It means the endpoint answered with a body that does not match the expected operation schema — most often an error payload, an auth challenge, or an API shape change.

Source

Thrown at litellm/llms/gemini/videos/transformation.py:321

        {
            "name": "operations/generate_1234567890",
            "metadata": {...},
            "done": false,
            "error": {...}
        }

        We return this as a VideoObject with:
        - id: operation name (used for polling)
        - status: "processing"
        - usage: includes duration_seconds and optional video_resolution for cost calculation
        """
        response_data: Final = raw_response.json()

        # Parse response using Pydantic model for type safety
        try:
            operation_response: Final = GeminiLongRunningOperationResponse(**response_data)
        except Exception as e:
            raise ValueError(f"Failed to parse operation response: {e}")

        operation_name: Final = operation_response.name
        if not operation_name:
            raise ValueError(f"No operation name in Veo response: {response_data}")

        if custom_llm_provider:
            video_id = encode_video_id_with_provider(operation_name, custom_llm_provider, model)
        else:
            video_id = operation_name

        video_obj: Final = VideoObject(
            id=video_id,
            object="video",
            status="processing",
            model=model,
        )

        usage_data: Final[dict[str, Any]] = {}

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Log the underlying Pydantic error (embedded in the message) and inspect the actual response JSON to see what came back (often an error object naming the real problem).
  2. Verify the project has Veo access/quotas and the region supports the model.
  3. Upgrade litellm to pick up the latest GeminiLongRunningOperationResponse schema.
  4. If the body is an error envelope, fix the root cause (billing/quota/region) rather than parsing.

Example fix

# before
video = litellm.generate_video(model='veo-3', prompt='...', api_key=key)

# after
try:
    video = litellm.generate_video(model='veo-3', prompt='...', api_key=key)
except ValueError as e:
    if 'Failed to parse operation response' in str(e):
        logger.error('Veo returned a non-operation body (quota/region/auth?): %s', e)
        raise
    raise
Defensive patterns

Strategy: try-catch

Validate before calling

def looks_like_operation(data: dict) -> bool:
    return isinstance(data, dict) and isinstance(data.get("name"), str) and bool(data["name"])

Type guard

def looks_like_operation(data: object) -> bool:
    return (
        isinstance(data, dict)
        and isinstance(data.get("name"), str)
        and len(data["name"]) > 0
    )

Try / catch

try:
    video = litellm.generate_video(model="veo-3", prompt=p, api_key=key)
except ValueError as e:
    if "Failed to parse operation response" in str(e):
        logger.error("Veo returned a non-operation body (quota/region/auth?): %s", e)
        raise VeoSubmissionError(str(e)) from e
    raise

Prevention

When it happens

Trigger: POST to Veo generateContent returns 200 with an unexpected body (quota/error object missing the operation fields), or a gateway returns JSON in a different shape; also Veo API schema evolution not yet covered by the installed litellm model.

Common situations: Quota-exceeded or region-restriction payloads returned instead of an operation; preview vs GA differences in the operation envelope; outdated litellm after Google changes Veo response fields; API key valid but project lacks Veo access.

Understand the failure class

Related errors


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