{"record":{"id":"ea28175629a91f5f","repo":"fishaudio/fish-speech","slug":"failed-to-decode-tokens-to-audio","errorCode":null,"errorMessage":"Failed to decode tokens to audio","messagePattern":"Failed to decode tokens to audio","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"tools/server/views.py","lineNumber":141,"sourceCode":"        decoder_model = model_manager.decoder_model\n\n        # Decode the audio\n        tokens = [torch.tensor(token, dtype=torch.int) for token in req.tokens]\n        start_time = time.time()\n        audios = batch_vqgan_decode(decoder_model, tokens)\n        logger.info(\n            f\"[EXEC] VQGAN decode time: {(time.time() - start_time) * 1000:.2f}ms\"\n        )\n        audios = [audio.astype(np.float16).tobytes() for audio in audios]\n\n        # Return the response\n        return ormsgpack.packb(\n            ServeVQGANDecodeResponse(audios=audios),\n            option=ormsgpack.OPT_SERIALIZE_PYDANTIC,\n        )\n    except Exception as e:\n        logger.error(f\"Error in VQGAN decode: {e}\", exc_info=True)\n        raise HTTPException(\n            HTTPStatus.INTERNAL_SERVER_ERROR, content=\"Failed to decode tokens to audio\"\n        )\n\n\n@routes.http.post(\"/v1/tts\")\nasync def tts(req: Annotated[ServeTTSRequest, Body(exclusive=True)]):\n    \"\"\"\n    Generate speech from text using TTS model.\n    \"\"\"\n    try:\n        # Get the model from the app\n        app_state = request.app.state\n        model_manager: ModelManager = app_state.model_manager\n        engine = model_manager.tts_inference_engine\n        sample_rate = engine.decoder_model.sample_rate\n\n        # Check if the text is too long\n        if app_state.max_text_length > 0 and len(req.text) > app_state.max_text_length:","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/fishaudio/fish-speech/blob/befe4001745417f8c42131739d862b8a6fdbd15a/tools/server/views.py#L123-L159","documentation":"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.","triggerScenarios":"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.","commonSituations":"Clients serializing tokens incorrectly (tolist on the wrong axis), using tokens from a different VQ model version, or truncated msgpack payloads.","solutions":["Check server logs for the underlying exception details","Ensure tokens match the shape produced by /v1/vqgan/encode (list of codebook arrays)","Regenerate tokens with the same model version the server loaded"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import numpy as np\ntokens = [np.asarray(t, dtype=np.int64) for t in tokens]\nassert all(t.ndim == 1 for t in tokens), \"each token array must be 1-D\"\nassert all(t.min() >= 0 and t.max() < num_codes for t in tokens)","typeGuard":null,"tryCatchPattern":"if resp.status_code == 500:\n    raise RuntimeError(\"token payload malformed or from a different VQ model version\")","preventionTips":["Round-trip tokens via /encode -> /decode in tests","Keep tokens from the same model version as the server"],"tags":["api-server","http-500","vqgan","serialization"],"backgroundTag":"invalid-token-payload","analyzedSha":"befe4001745417f8c42131739d862b8a6fdbd15a","analyzedAt":"2026-08-27T21:31:45.703Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}