fishaudio/fish-speech · error · HTTPException

Failed to decode tokens to audio

Error message

Failed to decode tokens to audio

What it means

The /v1/vqgan/decode endpoint converts token tensors back to audio; any exception during decoding is logged and converted to HTTP 500 'Failed to decode tokens to audio'. The token payload or model state is at fault.

Source

Thrown at tools/server/views.py:141

        decoder_model = model_manager.decoder_model

        # Decode the audio
        tokens = [torch.tensor(token, dtype=torch.int) for token in req.tokens]
        start_time = time.time()
        audios = batch_vqgan_decode(decoder_model, tokens)
        logger.info(
            f"[EXEC] VQGAN decode time: {(time.time() - start_time) * 1000:.2f}ms"
        )
        audios = [audio.astype(np.float16).tobytes() for audio in audios]

        # Return the response
        return ormsgpack.packb(
            ServeVQGANDecodeResponse(audios=audios),
            option=ormsgpack.OPT_SERIALIZE_PYDANTIC,
        )
    except Exception as e:
        logger.error(f"Error in VQGAN decode: {e}", exc_info=True)
        raise HTTPException(
            HTTPStatus.INTERNAL_SERVER_ERROR, content="Failed to decode tokens to audio"
        )


@routes.http.post("/v1/tts")
async def tts(req: Annotated[ServeTTSRequest, Body(exclusive=True)]):
    """
    Generate speech from text using TTS model.
    """
    try:
        # Get the model from the app
        app_state = request.app.state
        model_manager: ModelManager = app_state.model_manager
        engine = model_manager.tts_inference_engine
        sample_rate = engine.decoder_model.sample_rate

        # Check if the text is too long
        if app_state.max_text_length > 0 and len(req.text) > app_state.max_text_length:

View on GitHub (pinned to befe400174)

Solutions

  1. Check server logs for the underlying exception details
  2. Ensure tokens match the shape produced by /v1/vqgan/encode (list of codebook arrays)
  3. Regenerate tokens with the same model version the server loaded
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np
tokens = [np.asarray(t, dtype=np.int64) for t in tokens]
assert all(t.ndim == 1 for t in tokens), "each token array must be 1-D"
assert all(t.min() >= 0 and t.max() < num_codes for t in tokens)

Try / catch

if resp.status_code == 500:
    raise RuntimeError("token payload malformed or from a different VQ model version")

Prevention

When it happens

Trigger: Sending tokens with wrong shape/dtype/values (e.g. flat lists instead of [codes, t] shaped structures, out-of-range codebook indices) to /v1/vqgan/decode.

Common situations: Clients serializing tokens incorrectly (tolist on the wrong axis), using tokens from a different VQ model version, or truncated msgpack payloads.

Understand the failure class

Related errors


AI-assisted analysis of fishaudio/fish-speech@befe400174 (2026-08-27). Data as JSON: /api/errors/ea28175629a91f5f. Report an issue: GitHub.