conductor-oss/conductor · error · RuntimeException
Failed to check video status:
Error message
Failed to check video status:
What it means
OpenAIVideoModel.checkStatus() catches a generic Exception and wraps it in a RuntimeException with message "Failed to check video status: ". This is the polling path: GET /v1/videos/{jobId}. Any exception during status polling or result download (api.getVideoStatus, api.downloadVideo, api.downloadThumbnail) is caught and rethrown. The catch covers the entire method body including the completed-download branch.
Source
Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/openai/OpenAIVideoModel.java:149
} else if ("failed".equals(status.status())) {
metadata.setStatus("FAILED");
metadata.setErrorMessage(
"OpenAI video generation failed: %s".formatted(status.toString()));
log.error("OpenAI Sora video failed: id={}, response = {}", jobId, status);
return new VideoResponse(List.of(), metadata);
} else {
// queued or in_progress
metadata.setStatus("PROCESSING");
log.debug(
"OpenAI Sora video in progress: id={}, progress={}%",
jobId, status.progress());
return new VideoResponse(List.of(), metadata);
}
} catch (Exception e) {
log.error("Failed to check OpenAI video status for job {}", jobId, e);
throw new RuntimeException("Failed to check video status: " + e.getMessage(), e);
}
}
/**
* Maps OpenAI status strings to our canonical status values.
*
* <p>OpenAI uses: queued, in_progress, completed, failed
*/
private String mapStatus(String openaiStatus) {
return switch (openaiStatus) {
case "completed" -> "COMPLETED";
case "failed" -> "FAILED";
default -> "PROCESSING";
};
}
/**
* Resolves an input image specification to raw bytes.View on GitHub (pinned to cf7c3e4a8a)
Solutions
- Inspect getCause() and jobId in the log — the catch logs "Failed to check OpenAI video status for job {jobId}".
- For transient network errors during polling, retry checkStatus() with backoff (the Conductor async video workflow already polls).
- Verify the jobId is still valid — if the job was submitted long ago, it may have been purged.
- If the download itself fails (large MP4), check network bandwidth and OkHttp read timeout configuration.
Example fix
// before: single checkStatus call with no retry
VideoResponse resp = videoModel.checkStatus(jobId);
// after: retry with backoff for transient failures
VideoResponse resp;
int attempts = 0;
while (true) {
try {
resp = videoModel.checkStatus(jobId);
break;
} catch (RuntimeException e) {
if (++attempts >= 3) throw e;
Thread.sleep(5000L * attempts);
}
} Defensive patterns
Strategy: retry
Validate before calling
// Validate jobId before polling
if (jobId == null || jobId.isBlank()) {
throw new IllegalArgumentException("Job ID is required to check video status");
}
// Verify jobId format (OpenAI video IDs are typically alphanumeric with hyphens)
if (!jobId.matches("[a-zA-Z0-9_-]+")) {
throw new IllegalArgumentException("Invalid job ID format: " + jobId);
} Type guard
null
Try / catch
// checkStatus is inherently a polling operation — retry transient failures
int maxRetries = 3;
for (int attempt = 0; attempt <= maxRetries; attempt++) {
try {
VideoResponse response = videoModel.checkStatus(jobId);
return response;
} catch (RuntimeException e) {
if (attempt == maxRetries) throw e;
Throwable cause = e.getCause();
if (cause instanceof IOException || cause instanceof java.net.SocketTimeoutException) {
log.warn("Transient error polling video job {} (attempt {}), retrying", jobId, attempt + 1);
Thread.sleep(5000L * (attempt + 1));
continue;
}
throw e;
}
} Prevention
- Treat checkStatus as a retryable polling operation — transient network errors are expected.
- Log the jobId with each poll for traceability.
- Set a maximum job lifetime; if polling fails persistently, the job may have expired.
- Monitor for video download timeouts (large MP4 files) and adjust OkHttp read timeout.
When it happens
Trigger: checkVideoStatus() polls a job by jobId. Failure occurs when: the jobId is invalid or expired, the API key was revoked between submission and polling, network timeout downloading the large MP4 video binary, the video content endpoint returns an error, or a transient network blip during polling.
Common situations: Polling a job whose ID expired (OpenAI may purge old video records); network timeout downloading a large completed video; thumbnail download fails (though that path has its own try/catch); rate limit on status polling; API key revoked mid-job.
Related errors
- Failed to submit video generation:
- Empty response downloading image from
- Failed to download image from
- Embeddings API call failed:
- Speech API call failed:
AI-assisted analysis of conductor-oss/conductor@cf7c3e4a8a (2026-08-14).
Data as JSON: /api/errors/4ffb52b2d07f8c1c.
Report an issue: GitHub.