{"record":{"id":"0b98910896355c25","repo":"BerriAI/litellm","slug":"failed-to-parse-operation-response-e","errorCode":null,"errorMessage":"Failed to parse operation response: {e}","messagePattern":"Failed to parse operation response: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"litellm/llms/gemini/videos/transformation.py","lineNumber":321,"sourceCode":"        {\n            \"name\": \"operations/generate_1234567890\",\n            \"metadata\": {...},\n            \"done\": false,\n            \"error\": {...}\n        }\n\n        We return this as a VideoObject with:\n        - id: operation name (used for polling)\n        - status: \"processing\"\n        - usage: includes duration_seconds and optional video_resolution for cost calculation\n        \"\"\"\n        response_data: Final = raw_response.json()\n\n        # Parse response using Pydantic model for type safety\n        try:\n            operation_response: Final = GeminiLongRunningOperationResponse(**response_data)\n        except Exception as e:\n            raise ValueError(f\"Failed to parse operation response: {e}\")\n\n        operation_name: Final = operation_response.name\n        if not operation_name:\n            raise ValueError(f\"No operation name in Veo response: {response_data}\")\n\n        if custom_llm_provider:\n            video_id = encode_video_id_with_provider(operation_name, custom_llm_provider, model)\n        else:\n            video_id = operation_name\n\n        video_obj: Final = VideoObject(\n            id=video_id,\n            object=\"video\",\n            status=\"processing\",\n            model=model,\n        )\n\n        usage_data: Final[dict[str, Any]] = {}","sourceCodeStart":303,"sourceCodeEnd":339,"githubUrl":"https://github.com/BerriAI/litellm/blob/6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d/litellm/llms/gemini/videos/transformation.py#L303-L339","documentation":"Raised while handling a Veo long-running-operation response: the raw JSON is validated against the GeminiLongRunningOperationResponse Pydantic model, and any ValidationError is re-raised as ValueError('Failed to parse operation response: ...'). It means the endpoint answered with a body that does not match the expected operation schema — most often an error payload, an auth challenge, or an API shape change.","triggerScenarios":"POST to Veo generateContent returns 200 with an unexpected body (quota/error object missing the operation fields), or a gateway returns JSON in a different shape; also Veo API schema evolution not yet covered by the installed litellm model.","commonSituations":"Quota-exceeded or region-restriction payloads returned instead of an operation; preview vs GA differences in the operation envelope; outdated litellm after Google changes Veo response fields; API key valid but project lacks Veo access.","solutions":["Log the underlying Pydantic error (embedded in the message) and inspect the actual response JSON to see what came back (often an error object naming the real problem).","Verify the project has Veo access/quotas and the region supports the model.","Upgrade litellm to pick up the latest GeminiLongRunningOperationResponse schema.","If the body is an error envelope, fix the root cause (billing/quota/region) rather than parsing."],"exampleFix":"# before\nvideo = litellm.generate_video(model='veo-3', prompt='...', api_key=key)\n\n# after\ntry:\n    video = litellm.generate_video(model='veo-3', prompt='...', api_key=key)\nexcept ValueError as e:\n    if 'Failed to parse operation response' in str(e):\n        logger.error('Veo returned a non-operation body (quota/region/auth?): %s', e)\n        raise\n    raise\n","handlingStrategy":"try-catch","validationCode":"def looks_like_operation(data: dict) -> bool:\n    return isinstance(data, dict) and isinstance(data.get(\"name\"), str) and bool(data[\"name\"])","typeGuard":"def looks_like_operation(data: object) -> bool:\n    return (\n        isinstance(data, dict)\n        and isinstance(data.get(\"name\"), str)\n        and len(data[\"name\"]) > 0\n    )","tryCatchPattern":"try:\n    video = litellm.generate_video(model=\"veo-3\", prompt=p, api_key=key)\nexcept ValueError as e:\n    if \"Failed to parse operation response\" in str(e):\n        logger.error(\"Veo returned a non-operation body (quota/region/auth?): %s\", e)\n        raise VeoSubmissionError(str(e)) from e\n    raise","preventionTips":["Verify Veo access, billing, and regional availability for the model before submitting jobs.","Log the wrapped Pydantic error text — it reveals the actual body shape returned.","Upgrade litellm when Google changes Veo's operation response schema."],"tags":["gemini","veo","video-generation","pydantic","schema","parsing"],"backgroundTag":null,"analyzedSha":"6c2dcb801bf2b75c18f1bb24140e7cf57465cc4d","analyzedAt":"2026-08-15T07:12:03.035Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}