calesthio/OpenMontage · error · TimeoutError

Uploaded video did not finish processing in time

Error message

Uploaded video did not finish processing in time

What it means

Raised when an uploaded reference video stays in the Google Files API 'PROCESSING' state longer than _MAX_POLL_SECONDS. The tool uploads video bytes to the Files API and must wait until the file becomes ACTIVE before it can be referenced in a Gemini Omni generation request. If the server-side processing pipeline does not finish within the internal deadline, a TimeoutError aborts the wait.

Source

Thrown at tools/video/gemini_omni_video.py:265

        upload_resp = requests_mod.post(
            upload_url,
            headers={
                "X-Goog-Upload-Command": "upload, finalize",
                "X-Goog-Upload-Offset": "0",
                "Content-Length": str(len(video_bytes)),
            },
            data=video_bytes,
            timeout=300,
        )
        upload_resp.raise_for_status()
        file_info = upload_resp.json().get("file", {})

        # Wait until the uploaded video is processed before referencing it.
        deadline = time.time() + _MAX_POLL_SECONDS
        while str(file_info.get("state", "")).upper() == "PROCESSING":
            if time.time() > deadline:
                raise TimeoutError("Uploaded video did not finish processing in time")
            time.sleep(_POLL_INTERVAL_SECONDS)
            status_resp = requests_mod.get(
                f"{_BASE_URL}/{file_info.get('name')}",
                headers={"x-goog-api-key": api_key},
                timeout=15,
            )
            status_resp.raise_for_status()
            file_info = status_resp.json()
        if str(file_info.get("state", "")).upper() == "FAILED":
            raise RuntimeError("Files API failed to process the uploaded video")

        uri = file_info.get("uri")
        if not uri:
            raise RuntimeError(f"Files API response missing uri: {file_info}")
        return uri

    @staticmethod
    def _extract_output_video(data: dict[str, Any]) -> dict[str, Any] | None:

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Retry the call — Files API processing latency is often transient and a second attempt finishes in time.
  2. Reduce the input video size/duration (compress or trim) before uploading so server-side processing completes faster.
  3. Re-encode the video to a mainstream codec/container (e.g. H.264 MP4) that the Files API processes quickly.
  4. Increase _MAX_POLL_SECONDS in tools/video/gemini_omni_video.py if your workload regularly uses large references.
  5. Check Google Cloud status for Gemini API/Files API incidents if uploads consistently stall.

Example fix

// before
input.mp4  # 500MB 10-minute reference video, stalls in PROCESSING

// after (shell)
ffmpeg -i input.mp4 -t 15 -c:v libx264 -crf 28 -vf scale=1280:-2 input_small.mp4
# then pass input_small.mp4 as the video reference
Defensive patterns

Strategy: retry

Validate before calling

from pathlib import Path
import subprocess

def precheck_reference(path: str, max_mb: int = 100) -> None:
    p = Path(path)
    if not p.is_file():
        raise FileNotFoundError(path)
    if p.stat().st_size > max_mb * 1024 * 1024:
        raise ValueError(f"{path} is {p.stat().st_size // (1024*1024)}MB; compress before upload")
    # verify the container is readable so Files API processing won't stall
    subprocess.run(["ffprobe", "-v", "error", str(p)], check=True)

Try / catch

try:
    result = gemini_omni_video(inputs)
except TimeoutError as e:
    if "finish processing" in str(e):
        # transient: shrink input or retry with backoff
        raise RetryableError("files-api processing slow") from e
    raise

Prevention

When it happens

Trigger: Calling gemini_omni_video with a video reference (uploaded via _upload_video): the initial upload succeeds (upload_resp 200), but every subsequent GET {file.name} status check keeps returning state=PROCESSING past the deadline computed from _MAX_POLL_SECONDS.

Common situations: Large or long reference videos (hundreds of MB) that Google takes minutes to transcode; transient Google-side processing slowdowns; uploading unusual codecs/container formats that stall server-side processing; tight _MAX_POLL_SECONDS defaults combined with big payloads.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/db781bedfa0cf997. Report an issue: GitHub.