{"record":{"id":"ecbbbdcfa111dafb","repo":"conductor-oss/conductor","slug":"openai-video-api-status-check-failed-with-status","errorCode":null,"errorMessage":"OpenAI Video API status check failed with status %d: %s","messagePattern":"OpenAI Video API status check failed with status (.+?): (.+?)","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/providers/openai/api/OpenAIVideoApi.java","lineNumber":139,"sourceCode":"\n    /**\n     * Poll the status of a video generation job.\n     *\n     * @param videoId The video job ID\n     * @return Current status including progress percentage\n     */\n    public VideoStatusResponse getVideoStatus(String videoId) throws IOException {\n        Request request =\n                new Request.Builder()\n                        .url(baseUrl + \"/v1/videos/\" + videoId)\n                        .header(\"Authorization\", \"Bearer \" + apiKey)\n                        .get()\n                        .build();\n\n        try (Response response = httpClient.newCall(request).execute()) {\n            String responseBody = readResponseBody(response);\n            if (!response.isSuccessful()) {\n                throw new IOException(\n                        \"OpenAI Video API status check failed with status %d: %s\"\n                                .formatted(response.code(), responseBody));\n            }\n            return objectMapper.readValue(responseBody, VideoStatusResponse.class);\n        }\n    }\n\n    /**\n     * Download the completed video as a streaming InputStream. The caller is responsible for\n     * closing the returned stream.\n     *\n     * <p>Note: The underlying OkHttp response is not auto-closed here since the caller needs to\n     * consume the stream. The stream wrapper closes the response when the stream is closed.\n     *\n     * @param videoId The video job ID\n     * @return InputStream of the MP4 binary data\n     */\n    public InputStream downloadVideoStream(String videoId) throws IOException {","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/providers/openai/api/OpenAIVideoApi.java#L121-L157","documentation":"Thrown by OpenAIVideoApi.getVideoStatus when polling GET /v1/videos/{videoId} returns non-2xx. IOException carries the status code and response body. This is the status-poll call used to track an already-submitted job through completion.","triggerScenarios":"Polling with a videoId that has expired or never existed (404), an invalid key (401), or hitting poll rate limits (429). A 404 here typically means the result has aged out of OpenAI's retention window.","commonSituations":"Polling too long after generation completed and the asset TTL elapsed (404), a videoId copied incorrectly from the submit response, or aggressive polling tripping rate limits.","solutions":["On 404, stop polling: the job/asset is no longer available; treat as a terminal failure.","Respect the poll cadence implied by the job's progress and avoid tight poll loops that trigger 429.","Verify the videoId matches the 'id' field returned by submitVideoJob.","For 429, increase the poll interval and add backoff."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (StringUtils.isBlank(videoId)) {\n    throw new IllegalArgumentException(\"videoId is required to poll status\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    VideoStatusResponse status = videoApi.getVideoStatus(videoId);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"status 404\")) {\n        // asset expired/gone - stop polling, treat as terminal\n    } else if (e.getMessage().contains(\"status 429\")) {\n        // increase poll interval\n    } else {\n        throw e;\n    }\n}","preventionTips":["Poll at a reasonable interval to avoid rate limits.","Stop polling on 404 - the asset is no longer available.","Verify the videoId matches the submit response's 'id' field.","Cache the videoId to avoid re-deriving it each poll."],"tags":["openai","video","sora","http","polling"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}