conductor-oss/conductor · error · RuntimeException

Speech API call failed:

Error message

Speech API call failed: 

What it means

OpenAI.java wraps an IOException from OpenAISpeechApi.createSpeech() in a RuntimeException with message "Speech API call failed: ". This is the text-to-speech path (generateAudio), called when an AudioGenRequest is processed. The underlying IOException comes from the TTS API HTTP call failing (non-2xx or network error). The response is expected to be raw audio bytes, not JSON.

Source

Thrown at ai/src/main/java/org/conductoross/conductor/ai/providers/openai/OpenAI.java:173

            String responseFormat =
                    request.getResponseFormat() != null
                            ? request.getResponseFormat().toLowerCase()
                            : "mp3";

            var speechRequest =
                    new OpenAISpeechApi.SpeechRequest(
                            request.getModel(),
                            request.getText(),
                            request.getVoice(),
                            responseFormat,
                            request.getSpeed());
            byte[] audioData = speechApi.createSpeech(speechRequest);

            List<Media> media = new ArrayList<>();
            media.add(Media.builder().data(audioData).mimeType("audio/*").build());
            return LLMResponse.builder().media(media).build();
        } catch (IOException e) {
            throw new RuntimeException("Speech API call failed: " + e.getMessage(), e);
        }
    }

    @Override
    public VideoModel getVideoModel() {
        return this.videoModel;
    }

    @Override
    public LLMResponse generateVideo(VideoGenRequest request) {
        VideoOptions options = getVideoOptions(request);
        VideoPrompt videoPrompt = new VideoPrompt(request.getPrompt(), options);
        VideoResponse response = videoModel.call(videoPrompt);

        return LLMResponse.builder()
                .jobId(response.getMetadata().getJobId())
                .finishReason(response.getMetadata().getStatus())
                .build();

View on GitHub (pinned to cf7c3e4a8a)

Solutions

  1. Inspect getCause() — the IOException message contains the HTTP status and response body.
  2. Verify the model is a TTS model (tts-1, tts-1-hd, gpt-4o-mini-tts).
  3. Verify the voice is one OpenAI supports (alloy, echo, fable, onyx, nova, shimmer, or custom voices for gpt-4o-mini-tts).
  4. Check responseFormat is a valid TTS format (mp3, opus, aac, flac, wav, pcm).

Example fix

// before
AudioGenRequest req = new AudioGenRequest();
req.setModel("gpt-4o"); // wrong — not a TTS model
// after
req.setModel("tts-1-hd");
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate TTS request before calling generateAudio()
AudioGenRequest req = /* ... */;
Set<String> ttsModels = Set.of("tts-1", "tts-1-hd", "gpt-4o-mini-tts");
if (!ttsModels.contains(req.getModel())) {
    throw new IllegalArgumentException(
        "Model '" + req.getModel() + "' is not a TTS model. Use: " + ttsModels);
}
if (req.getText() == null || req.getText().isBlank()) {
    throw new IllegalArgumentException("Text is required for speech generation");
}
Set<String> validVoices = Set.of("alloy", "echo", "fable", "onyx", "nova", "shimmer");
if (req.getVoice() != null && !validVoices.contains(req.getVoice())) {
    log.warn("Voice '{}' is not a standard voice", req.getVoice());
}

Type guard

null

Try / catch

try {
    LLMResponse audio = llm.generateAudio(request);
} catch (RuntimeException e) {
    Throwable cause = e.getCause();
    if (cause instanceof IOException) {
        log.error("TTS API failed: {}", cause.getMessage());
    }
    throw e;
}

Prevention

When it happens

Trigger: generateAudio() is called with a TTS request (model, text, voice, format, speed) and the POST /v1/audio/speech request fails: invalid model (e.g. using a non-TTS model name), unsupported voice, 401 auth, 429 rate limit, or network error.

Common situations: Using a non-TTS model name (e.g. "gpt-4o" instead of "tts-1" or "tts-1-hd"); specifying a voice the model doesn't support; API key lacks TTS access; network timeout on long text input.

Related errors


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