conductor-oss/conductor · error · RuntimeException

Failed to submit video generation:

Error message

Failed to submit video generation: 

What it means

OpenAIVideoModel.call() catches a generic Exception and wraps it in a RuntimeException with message "Failed to submit video generation: ". This is the async job-submission path for OpenAI Sora: POST /v1/videos. Any exception during job submission (API error, image resolution failure, JSON parse error, or IOException from submitVideoJob) is caught and rethrown. The catch is broad (Exception) because the method also resolves input images and detects MIME types.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/openai/OpenAIVideoModel.java:92

                    new OpenAIVideoApi.VideoCreateParams(
                            text, opts.getModel(), size, seconds, imageBytes, imageMimeType);

            OpenAIVideoApi.VideoStatusResponse status = api.submitVideoJob(params);

            log.info(
                    "OpenAI Sora video job submitted: id={}, status={}",
                    status.id(),
                    status.status());

            VideoResponseMetadata metadata = new VideoResponseMetadata();
            metadata.setJobId(status.id());
            metadata.setStatus(mapStatus(status.status()));

            return new VideoResponse(List.of(), metadata);

        } catch (Exception e) {
            log.error("Failed to submit OpenAI video generation job", e);
            throw new RuntimeException("Failed to submit video generation: " + e.getMessage(), e);
        }
    }

    @Override
    public VideoResponse checkStatus(String jobId) {
        try {
            OpenAIVideoApi.VideoStatusResponse status = api.getVideoStatus(jobId);

            VideoResponseMetadata metadata = new VideoResponseMetadata();
            metadata.setJobId(status.id());
            metadata.setStatus(mapStatus(status.status()));
            metadata.put("progress", status.progress());

            if ("completed".equals(status.status())) {
                // Download the video MP4 as bytes
                // Use direct byte storage to avoid base64 encoding overhead (~33% memory savings)
                byte[] videoBytes = api.downloadVideo(jobId);

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect getCause() for the root exception — it may be an IOException (API error), RuntimeException (image download), or IllegalArgumentException.
  2. Verify the API key has Sora access (Sora requires specific account tier/allowlist).
  3. Verify the model name is a valid Sora model (sora, sora-2, etc.).
  4. If using image-to-video, verify the inputImage URL is reachable and valid (see errors 214, 215).
  5. Verify size and duration match Sora's supported values (e.g. 1280x720, duration in seconds).

Example fix

// before
VideoGenRequest req = new VideoGenRequest();
req.setInputImage("https://expired.example.com/img.jpg"); // unreachable
// after
req.setInputImage("https://valid-cdn.example.com/img.jpg");
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate video generation request before submitting
VideoGenRequest req = /* ... */;
if (req.getModel() == null || req.getModel().isBlank()) {
    throw new IllegalArgumentException("Video model name is required");
}
if (req.getPrompt() == null || req.getPrompt().isBlank()) {
    throw new IllegalArgumentException("Prompt is required for video generation");
}
// If image-to-video, validate the input image URL is reachable
if (req.getInputImage() != null && !req.getInputImage().isBlank()
    && (req.getInputImage().startsWith("http://") || req.getInputImage().startsWith("https://"))) {
    try {
        URI uri = URI.create(req.getInputImage());
        // Optionally do a HEAD request to check reachability
    } catch (IllegalArgumentException e) {
        throw new IllegalArgumentException("Invalid inputImage URL: " + req.getInputImage());
    }
}

Type guard

null

Try / catch

try {
    VideoResponse response = videoModel.call(prompt);
} catch (RuntimeException e) {
    Throwable cause = e.getCause();
    String msg = cause != null ? cause.getMessage() : e.getMessage();
    log.error("Video job submission failed: {}", msg);
    // If image download failed, fix the URL and retry
    if (msg.contains("download image") || msg.contains("Empty response")) {
        throw new IllegalArgumentException(
            "Input image URL is unreachable or returns empty. Use a data: URI instead.", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: generateVideo() calls videoModel.call(videoPrompt) which submits a Sora job. Failure occurs when: invalid/expired API key, Sora not available for the account, invalid size or duration parameter, input image URL unreachable (see errors 214/215), malformed image data, or network error reaching the Sora API endpoint.

Common situations: API key without Sora access (Sora is a limited-access model); using a size OpenAI doesn't accept; image-to-video with a broken/expired image URL; Sora endpoint region mismatch; malformed base64 image input.

Related errors


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