BerriAI/litellm · error · ValueError

Invalid operation name format: {operation_name}. Expected fo

Error message

Invalid operation name format: {operation_name}. Expected format: projects/PROJECT/locations/LOCATION/publishers/google/models/MODEL/operations/OPERATION_ID

What it means

When polling a Veo operation, LiteLLM rebuilds the fetchPredictOperation URL from the stored operation name by splitting it on "/" and taking index 7 as the model (`projects/0/P/1? ... publishers/5 google/6 models/7 -> index 7 is MODEL`). If the string has fewer than 8 slash-separated segments, `extract_model_from_operation_name` returns None and this ValueError raises. Practically: the video_id passed to video_status()/content download is not a full Vertex operation name.

Source

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

        return video_obj

    def transform_video_status_retrieve_request(
        self,
        video_id: str,
        api_base: str,
        litellm_params: GenericLiteLLMParams,
        headers: dict,
    ) -> tuple[str, dict]:
        """
        Transform the video status retrieve request for Veo API.

        Veo polls operations using :fetchPredictOperation endpoint with POST request.
        """
        operation_name: Final = extract_original_video_id(video_id)
        model: Final = self.extract_model_from_operation_name(operation_name)

        if not model:
            raise ValueError(
                f"Invalid operation name format: {operation_name}. "
                "Expected format: projects/PROJECT/locations/LOCATION/publishers/google/models/MODEL/operations/OPERATION_ID"
            )

        # Construct the full URL including model ID
        # URL format: https://LOCATION-aiplatform.googleapis.com/v1/projects/PROJECT/locations/LOCATION/publishers/google/models/MODEL:fetchPredictOperation
        # Strip trailing slashes from api_base and append model
        url: Final = f"{api_base.rstrip('/')}/{model}:fetchPredictOperation"

        # Request body contains the operation name
        params: Final = {"operationName": operation_name}

        return url, params

    def transform_video_status_retrieve_response(
        self,
        raw_response: httpx.Response,
        logging_obj: LiteLLMLoggingObj,

View on GitHub (pinned to 77b7c6c40c)

Solutions

  1. Use the exact id returned by the generation call: video = litellm.video_generation(...); litellm.video_status(video_id=video.id) — do not truncate it.
  2. If you store IDs, store the full `projects/.../operations/OP` string (or the provider-encoded VideoObject.id) unchanged.
  3. If you only have OPERATION_ID, reconstruct: f"projects/{project}/locations/{location}/publishers/google/models/{model}/operations/{op_id}".
  4. Do not pass IDs obtained from non-Vertex video APIs to the Vertex status route.

Example fix

# before
litellm.video_status(video_id="5f2d3b4c-...")  # short op id only -> raises

# after
result = litellm.video_generation(model="vertex_ai/veo-2.0-generate-001", prompt=p, vertex_project=proj)
litellm.video_status(video_id=result.id)  # full projects/.../operations/... name
Defensive patterns

Strategy: type-guard

Validate before calling

import re

OPERATION_RE = re.compile(r"^projects/[^/]+/locations/[^/]+/publishers/[^/]+/models/[^/]+/operations/[^/]+$")

def is_full_vertex_operation(video_id: str) -> bool:
    return bool(OPERATION_RE.match(video_id))

Type guard

def is_full_vertex_operation(video_id: str) -> bool:
    parts = video_id.split("/")
    return len(parts) >= 8 and parts[0] == "projects" and "operations" in parts

Try / catch

try:
    status = litellm.video_status(video_id=vid, vertex_project=proj)
except ValueError as e:
    if "Invalid operation name format" in str(e):
        raise ValueError(f"Stored video_id is truncated: {vid!r}; persist the full operation name") from e
    raise

Prevention

When it happens

Trigger: Calling litellm.video_status(video_id=...) with a hand-truncated or edited ID (e.g. just the OPERATION_ID tail), an ID from a different provider, or a provider-prefixed ID that was double-encoded/decoded so the operation path was lost.

Common situations: Persisting only the short operation ID instead of the full VideoObject.id; string-munging IDs between services; replaying IDs captured from a non-Vertex (e.g. Gemini API) run.

Related errors


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