BerriAI/litellm · warning · ValueError

Video generation is not complete yet. Please check status wi

Error message

Video generation is not complete yet. Please check status with video_status() before downloading.

What it means

Raised when downloading Veo video content if the polled operation still has `done: false`. Veo generation is asynchronous — the initial call returns an operation, and content retrieval via transform_video_content is only valid after the operation completes. This error is a guard telling you the download was attempted too early; poll video_status() until done before fetching bytes.

Source

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

        Since we need to make an HTTP call here, we'll use the same fetchPredictOperation
        approach as status retrieval.
        """
        return self.transform_video_status_retrieve_request(video_id, api_base, litellm_params, headers)

    def transform_video_content_response(
        self,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,
    ) -> bytes:
        """
        Transform the Veo video content download response.

        Extracts the base64 encoded video from the response and decodes it to bytes.
        """
        response_data: Final = _parse_veo_operation(raw_response)

        if not response_data.get("done", False):
            raise ValueError(
                "Video generation is not complete yet. Please check status with video_status() before downloading."
            )

        try:
            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

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Poll until completion: loop on video_status(video_id=...) and only download when status shows done (status "completed").
  2. Respect the polling pattern: Veo operations take tens of seconds to minutes; add exponential backoff between polls (e.g. 5s, 10s, 20s).
  3. Check for an error field in the status response — failed operations never become done and should be surfaced as a failure, not retried for download.
  4. If you need a blocking API, wrap generation + poll + download in one helper instead of calling download directly.

Example fix

# before
result = litellm.video_generation(model="vertex_ai/veo-2.0-generate-001", prompt=p, vertex_project=proj)
import time; time.sleep(10)
content = litellm.retrieve_video_content(video_id=result.id)  # may raise: not done

# after
result = litellm.video_generation(model="vertex_ai/veo-2.0-generate-001", prompt=p, vertex_project=proj)
while True:
    status = litellm.video_status(video_id=result.id, vertex_project=proj)
    if status.status == "completed":
        break
    if status.status == "failed":
        raise RuntimeError(status)
    time.sleep(10)
content = litellm.retrieve_video_content(video_id=result.id, vertex_project=proj)
Defensive patterns

Strategy: retry

Validate before calling

def wait_for_veo(video_id: str, project: str, timeout_s: int = 600) -> None:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        st = litellm.video_status(video_id=video_id, vertex_project=project)
        if st.status == "completed":
            return
        if st.status == "failed":
            raise RuntimeError(f"veo operation failed: {st}")
        time.sleep(10)
    raise TimeoutError("veo generation did not finish in time")

Try / catch

try:
    content = litellm.retrieve_video_content(video_id=vid, vertex_project=proj)
except ValueError as e:
    if "not complete yet" in str(e):
        time.sleep(15)  # then re-poll; or treat as signal to extend the polling loop
        content = litellm.retrieve_video_content(video_id=vid, vertex_project=proj)
    else:
        raise

Prevention

When it happens

Trigger: Calling aretrieve_video_content / content download immediately after video_generation returns (status "processing"), or before the video_status() poll shows done=true; long generations (30-60s+) interrupted by an early fixed-delay download.

Common situations: Using a fixed sleep(10) then download instead of polling; treating the generation response as synchronous; retry loops that skip the status check.

Related errors


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