BerriAI/litellm · error · ValueError

Failed to extract video data: {e}

Error message

Failed to extract video data: {e}

What it means

Thrown by the Vertex AI Veo video transformation while extracting generated video bytes from a completed operation response. The code indexes videos[0] inside a try block and converts KeyError/IndexError into this ValueError, meaning the response JSON lacked the 'videos' key or the list was empty. The '{e}' part names the original missing key (e.g. KeyError: 'videos'). It signals that the operation payload does not match the expected generateVideoResponse shape.

Source

Thrown at litellm/llms/vertex_ai/videos/transformation.py:570

            video_response: Final = response_data.get("response", {})
            videos: Final = video_response.get("videos", [])

            if not videos or len(videos) == 0:
                raise ValueError("No video data found in completed operation")

            # Get the first video
            video_data: Final = videos[0]
            base64_encoded: Final = video_data.get("bytesBase64Encoded")

            if not base64_encoded:
                raise ValueError("No base64 encoded video data found")

            # Decode base64 to bytes
            video_bytes: Final = base64.b64decode(base64_encoded)
            return video_bytes

        except (KeyError, IndexError) as e:
            raise ValueError(f"Failed to extract video data: {e}")

    def transform_video_remix_request(
        self,
        video_id: str,
        prompt: str,
        api_base: str,
        litellm_params: GenericLiteLLMParams,
        headers: dict,
        extra_body: dict[str, object] | None = None,
    ) -> tuple[str, dict]:
        """
        Video remix is not supported by Veo API.
        """
        raise NotImplementedError(
            "Video remix is not supported by Vertex AI Veo. Please use video_generation() to create new videos."
        )

    def transform_video_remix_response(

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Only transform the response after the operation has done=True and contains a 'response' object
  2. Print/inspect the raw operation JSON to see whether 'videos' exists or an 'error' field is present instead
  3. If the operation carries an error, surface it and retry generation rather than parsing for videos
  4. Check for Vertex AI API shape changes if the same code worked on an older response capture

Example fix

# before
video = litellm.video_status_retrieve(video_id=vid, custom_llm_provider="vertex_ai")
bytes_data = video.data[0]  # crashes downstream when videos missing

# after
op = fetch_raw_operation(vid)
if not op.get("done") or "videos" not in op.get("response", {}):
    raise RuntimeError(f"Veo operation not ready or errored: {op}")
video = litellm.video_status_retrieve(video_id=vid, custom_llm_provider="vertex_ai")
Defensive patterns

Strategy: validation

Validate before calling

def veo_response_has_videos(operation: dict) -> bool:
    return (
        operation.get("done") is True
        and isinstance(operation.get("response"), dict)
        and isinstance(operation["response"].get("videos"), list)
        and len(operation["response"]["videos"]) > 0
    )

if not veo_response_has_videos(op):
    raise RuntimeError(f"Veo operation has no videos yet: {op.get('error', op)}")

Type guard

from typing import TypedDict

class VeoVideo(TypedDict):
    bytesBase64Encoded: str
    mimeType: str

def is_veo_video_list(value: object) -> bool:
    return (
        isinstance(value, list)
        and len(value) > 0
        and isinstance(value[0], dict)
        and "bytesBase64Encoded" in value[0]
    )

Try / catch

try:
    video = litellm.video_status_retrieve(video_id=vid, custom_llm_provider="vertex_ai")
except ValueError as e:
    if "Failed to extract video data" in str(e):
        # response shape unexpected: log raw operation and treat as failed generation
        raise RuntimeError(f"Veo response missing videos: {e}") from e
    raise

Prevention

When it happens

Trigger: Calling litellm.video_generation / video_status_retrieve with a vertex_ai/veo model where the polled operation response has no 'videos' array: polling before the operation is done, an operation that completed with an error instead of output, or a truncated/modified API response.

Common situations: Polling a Veo predictLongRunning operation too early; generation finished with 'error' instead of 'response.videos'; Google changing/renaming response fields; testing against recorded/mocked responses missing the videos field.

Related errors


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