BerriAI/litellm · warning · ValueError

Source video generation is not complete yet. Check the video

Error message

Source video generation is not complete yet. Check the video status before editing.

What it means

Raised by the Vertex edit request transform when the pre-fetched source operation JSON has done != True. Veo edits read the finished source video out of its predictLongRunning operation, so editing before generation completes has nothing to read and LiteLLM fails fast with this ValueError.

Source

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

        litellm_params: GenericLiteLLMParams,
        headers: dict,
        extra_body: dict[str, object] | None = None,
        prefetched_source_data: dict[str, Any] | None = None,
    ) -> tuple[str, dict]:
        """
        Build a predictLongRunning edit request from the pre-fetched source video.

        The actual fetchPredictOperation HTTP call is hoisted into the handler so
        it can use the shared async/sync httpx client instead of blocking the loop.
        """
        if prefetched_source_data is None:
            raise ValueError(
                "prefetched_source_data is required for Vertex AI video edit. "
                "Ensure get_video_edit_prefetch_params is called by the handler."
            )

        if not prefetched_source_data.get("done", False):
            raise ValueError("Source video generation is not complete yet. Check the video status before editing.")

        source_response: Final[_VeoOperationResponse] = prefetched_source_data.get("response", {})
        videos: Final = source_response.get("videos", [])
        if not videos:
            raise ValueError("No videos found in the completed operation. Cannot edit.")

        source_video: Final = videos[0]
        video_input: Final[dict[str, str]] = {}
        if "gcsUri" in source_video:
            video_input["gcsUri"] = source_video["gcsUri"]
        elif "bytesBase64Encoded" in source_video:
            video_input["bytesBase64Encoded"] = source_video["bytesBase64Encoded"]
            video_input["mimeType"] = source_video.get("mimeType", "video/mp4")
        else:
            raise ValueError("Source video has neither gcsUri nor bytesBase64Encoded. Cannot edit.")

        operation_name: Final = extract_original_video_id(video_id)
        model: Final = self.extract_model_from_operation_name(operation_name) or ""

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Poll litellm.video_status_retrieve(video_id=...) until status is completed before calling video_edit
  2. Add a small delay/backoff between polls — Veo generation typically takes tens of seconds to minutes
  3. If the operation never completes, inspect the raw operation for an error field and retry generation

Example fix

# before
litellm.video_edit(video_id=vid, prompt="add fireworks", custom_llm_provider="vertex_ai")

# after
while True:
    st = litellm.video_status_retrieve(video_id=vid, custom_llm_provider="vertex_ai")
    if st.status == "completed":
        break
    if st.status == "failed":
        raise RuntimeError(st.error)
    time.sleep(10)
litellm.video_edit(video_id=vid, prompt="add fireworks", custom_llm_provider="vertex_ai")
Defensive patterns

Strategy: retry

Validate before calling

def wait_for_veo_video(video_id: str, timeout_s: int = 600, interval_s: int = 10) -> None:
    deadline = time.time() + timeout_s
    while time.time() < deadline:
        st = litellm.video_status_retrieve(video_id=video_id, custom_llm_provider="vertex_ai")
        if st.status == "completed":
            return
        if st.status == "failed":
            raise RuntimeError(f"veo generation failed: {getattr(st, 'error', None)}")
        time.sleep(interval_s)
    raise TimeoutError(f"video {video_id} not ready after {timeout_s}s")

Type guard

def operation_is_done(operation: dict) -> bool:
    return operation.get("done") is True

Try / catch

for attempt in range(max_attempts):
    try:
        litellm.video_edit(video_id=vid, prompt=p, custom_llm_provider="vertex_ai")
        break
    except ValueError as e:
        if "not complete yet" not in str(e) or attempt == max_attempts - 1:
            raise
        time.sleep(poll_interval)

Prevention

When it happens

Trigger: Calling litellm.video_edit(video_id=<operation still running>, ...) — e.g. immediately after video_generation returns status='processing', or when polling of the source operation was skipped/short-circuited.

Common situations: Fire-and-forget pipelines that chain generate→edit without waiting; poll loops with too-short intervals or a bug that treats 'processing' as done; editing a video whose generation silently stalled.

Related errors


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