conductor-oss/conductor · error · RuntimeException

Failed to check video status: {message}

Error message

Failed to check video status: {message}

What it means

GeminiVideoModel.checkStatus() catches any Exception during the Veo video operation polling (api.getVideosOperation) and wraps it. The operation name (jobId) is included in the error log. The original exception is preserved as the cause. This covers failures when polling a previously-submitted long-running video generation operation.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/gemini/GeminiVideoModel.java:166

                    }
                }

                metadata.setStatus("COMPLETED");
                log.info(
                        "Gemini Veo video completed: operation={}, videos={}",
                        jobId,
                        generations.size());
                return new VideoResponse(generations, metadata);

            } else {
                metadata.setStatus("PROCESSING");
                log.debug("Gemini Veo video in progress: operation={}", jobId);
                return new VideoResponse(List.of(), metadata);
            }

        } catch (Exception e) {
            log.error("Failed to check Gemini Veo video status for operation {}", jobId, e);
            throw new RuntimeException("Failed to check video status: " + e.getMessage(), e);
        }
    }

    private byte[] downloadFromUrl(String url) {
        okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();
        try (okhttp3.Response response = httpClient.newCall(request).execute()) {
            if (response.body() == null) {
                throw new RuntimeException("Empty response downloading image from " + url);
            }
            return response.body().bytes();
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new RuntimeException("Failed to download image from " + url, e);
        }
    }
}

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect getCause() for the specific failure.
  2. Verify the jobId/operation name is complete and matches what was returned from the initial call() submission.
  3. Ensure the same API key / Vertex AI credentials and project are used for both submission (call) and polling (checkStatus).
  4. Handle expired operations gracefully — if the operation is gone, re-submit the generation.
  5. Implement retry with backoff for transient polling failures.
Defensive patterns

Strategy: retry

Validate before calling

// Validate operation name before polling
void validateOperationName(String jobId) {
    if (jobId == null || jobId.isBlank()) {
        throw new IllegalArgumentException("Job ID / operation name is required");
    }
    // Veo operation names follow a predictable pattern
    if (!jobId.startsWith("operations/")) {
        throw new IllegalArgumentException(
            "Invalid Veo operation name: " + jobId
            + " — expected format: operations/...");
    }
}

Try / catch

// Retry polling with backoff for transient failures
for (int attempt = 0; attempt < 3; attempt++) {
    try {
        return videoModel.checkStatus(jobId);
    } catch (RuntimeException e) {
        if (attempt < 2 && isTransient(e.getCause())) {
            Thread.sleep((long) Math.pow(2, attempt) * 5000);
            continue;
        }
        throw new RuntimeException(
            "Failed to poll Veo operation " + jobId
            + " — verify credentials match submission", e);
    }
}

Prevention

When it happens

Trigger: The api.getVideosOperation(jobId) call fails: the operation name is invalid or malformed, the operation has expired or been garbage-collected by Google, API key changed since job submission, network failure during polling, or the Vertex AI project/location doesn't match the one used for submission.

Common situations: Polling a job ID from a previous Conductor restart where credentials changed. Job ID truncated or corrupted in storage. Operation expired (Veo operations have a retention window). Network blip during a polling loop. Different API key used for submission vs. polling.

Related errors


AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14). Data as JSON: /api/errors/5a1e29a0eb9d2e37. Report an issue: GitHub.