{"record":{"id":"03e7f67c5e3cd6d0","repo":"conductor-oss/conductor","slug":"failed-to-download-from-url","errorCode":null,"errorMessage":"Failed to download from {url}","messagePattern":"Failed to download from (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"ai/src/main/java/org/conductoross/conductor/ai/providers/gemini/GeminiVertex.java","lineNumber":199,"sourceCode":"                }\n            }\n            builder.media(mediaList);\n        }\n\n        return builder.build();\n    }\n\n    private byte[] downloadFromUrl(String url) {\n        okhttp3.Request request = new okhttp3.Request.Builder().url(url).get().build();\n        try (okhttp3.Response response = httpClient.newCall(request).execute()) {\n            if (response.body() == null) {\n                throw new RuntimeException(\"Empty response downloading from \" + url);\n            }\n            return response.body().bytes();\n        } catch (RuntimeException e) {\n            throw e;\n        } catch (Exception e) {\n            throw new RuntimeException(\"Failed to download from \" + url, e);\n        }\n    }\n\n    @Override\n    public LLMResponse generateAudio(AudioGenRequest request) {\n        GeminiApi.SpeechConfig speechConfig =\n                new GeminiApi.SpeechConfig(\n                        new GeminiApi.VoiceConfig(\n                                new GeminiApi.PrebuiltVoiceConfig(request.getVoice())));\n        GeminiApi.GenerationConfig genConfig =\n                new GeminiApi.GenerationConfig(\n                        null,\n                        null,\n                        null,\n                        request.getMaxTokens(),\n                        request.getStopWords(),\n                        request.getFrequencyPenalty(),\n                        null,","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/conductor-oss/conductor/blob/cf7c3e4a8adfb158be778ab1ec525323c363cd3a/ai/src/main/java/org/conductoross/conductor/ai/providers/gemini/GeminiVertex.java#L181-L217","documentation":"GeminiVertex.downloadFromUrl() catches any checked Exception (IOException, etc.) during the media URL download and wraps it with this message. RuntimeException (including error 192) is rethrown unchanged first. The original exception is preserved as the cause. This covers all transport-layer failures during media download from Gemini-provided URLs.","triggerScenarios":"IOException during the OkHttp GET to the Gemini-provided media URL: connection timeout, SSL handshake failure, connection reset, DNS resolution failure for the Google storage/CDN host.","commonSituations":"Network partition or firewall blocking Google Cloud Storage / CDN hosts. OkHttp readTimeout too short for large video files. Transient network blip during download. Proxy misconfiguration stripping or mangling the download request.","solutions":["Inspect getCause() for the specific IOException.","Implement retry logic — media downloads from signed URLs are often transient-failure recoverable if the URL hasn't expired.","Increase OkHttp readTimeout for video/media downloads (videos can be large).","Verify network connectivity to the Google Cloud Storage / CDN domain in the URL."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Validate network reachability before download\nvoid validateDownloadUrl(String url) {\n    try {\n        new java.net.URL(url).openConnection().connect();\n    } catch (java.io.IOException e) {\n        throw new IllegalArgumentException(\n            \"Cannot reach media URL: \" + url, e);\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    return vertex.downloadFromUrl(url);\n} catch (RuntimeException e) {\n    if (!e.getMessage().startsWith(\"Empty response\")\n            && e.getCause() instanceof java.io.IOException) {\n        // Transient network error — retry with backoff\n        Thread.sleep(3000);\n        return vertex.downloadFromUrl(url);\n    }\n    throw e;\n}","preventionTips":["Verify the Conductor host can reach Google Cloud Storage / CDN domains.","Configure OkHttp with a read timeout large enough for video files.","Implement retry with exponential backoff for transient IOException causes.","Log the cause exception to distinguish DNS failures from TLS errors from timeouts."],"tags":["gemini","download","network","io","vertex-ai"],"backgroundTag":null,"analyzedSha":"cf7c3e4a8adfb158be778ab1ec525323c363cd3a","analyzedAt":"2026-08-14T03:33:19.897Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}