odysseus-dev/odysseus · error · HTTPException

Synthesis failed

Error message

Synthesis failed

What it means

HTTP 500 from POST /api/tts/synthesize with format=='base64' when tts_service.synthesize_to_base64(text) returns an empty/falsy value. The call completed without raising but produced no audio, which the route treats as a hard failure rather than returning an empty clip.

Source

Thrown at routes/tts_routes.py:43

            return tts_service.get_stats()
        except Exception as e:
            logger.error(f"Failed to get TTS stats: {e}")
            raise HTTPException(status_code=500, detail=str(e))

    @router.post("/synthesize")
    async def synthesize_speech(request: TTSRequest):
        """Synthesize speech from text"""
        try:
            if not tts_service.available:
                raise HTTPException(
                    status_code=503,
                    detail={"message": "TTS service not available"}
                )
            
            if request.format == "base64":
                audio_b64 = tts_service.synthesize_to_base64(request.text)
                if not audio_b64:
                    raise HTTPException(
                        status_code=500,
                        detail={"message": "Synthesis failed"}
                    )
                return {"audio": audio_b64}
            
            else:  # audio format
                audio_data = tts_service.synthesize(request.text)
                if not audio_data:
                    raise HTTPException(
                        status_code=500,
                        detail={"message": "Synthesis failed"}
                    )
                
                # Detect format from magic bytes (MP3: ID3 tag or sync word ff e0+)
                is_mp3 = audio_data[:3] == b'ID3' or (len(audio_data) >= 2 and audio_data[0] == 0xff and (audio_data[1] & 0xe0) == 0xe0)
                mime = "audio/mpeg" if is_mp3 else "audio/wav"
                return Response(
                    content=audio_data,

View on GitHub (pinned to f9235ebbf1)

Solutions

  1. Retry with plain alphanumeric text to confirm the engine works at all
  2. Check service logs for swallowed provider errors during synthesis; verify provider credentials/quota
  3. Clear the TTS cache (POST /api/tts/clear-cache) in case a corrupt empty entry is being served
  4. If reproducible, instrument tts_service.synthesize_to_base64 — the falsy return hides the real error
Defensive patterns

Strategy: retry

Validate before calling

if (!text.trim()) throw new Error('nothing to synthesize');

Try / catch

if (resp.status === 500 && body.message === 'Synthesis failed') { backoffRetry(2); }

Prevention

When it happens

Trigger: POST /api/tts/synthesize with {"format":"base64"} where the engine silently produces nothing: text made only of characters the engine drops (emoji/whitespace), provider returned HTTP 200 with an empty body, or a corrupt cache entry served as empty.

Common situations: Text containing only emoji or invisible characters; provider quota exhausted and errors swallowed; corrupted cache entry returning an empty hit.

Related errors


AI-assisted analysis of odysseus-dev/odysseus@f9235ebbf1 (2026-08-14). Data as JSON: /api/errors/9567ea84d6b19c8e. Report an issue: GitHub.