{"record":{"id":"ede40051f85886c4","repo":"chenhg5/cc-connect","slug":"minimax-tts-no-audio-data-received","errorCode":null,"errorMessage":"minimax tts: no audio data received","messagePattern":"minimax tts: no audio data received","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/tts.go","lineNumber":405,"sourceCode":"\t\t// chunks; the final status=2 chunk re-sends the full audio as a\n\t\t// trailer for non-stream clients. Appending the trailer doubles the\n\t\t// audio length and makes the spoken text play twice, so skip it.\n\t\tif chunk.Data.Status == 2 {\n\t\t\tbreak\n\t\t}\n\t\tif chunk.Data.Audio != \"\" {\n\t\t\taudioBytes, err := hex.DecodeString(chunk.Data.Audio)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, \"\", fmt.Errorf(\"minimax tts: decode audio hex: %w\", err)\n\t\t\t}\n\t\t\taudioBuf.Write(audioBytes)\n\t\t}\n\t}\n\tif err := scanner.Err(); err != nil {\n\t\treturn nil, \"\", fmt.Errorf(\"minimax tts: read SSE stream: %w\", err)\n\t}\n\tif audioBuf.Len() == 0 {\n\t\treturn nil, \"\", fmt.Errorf(\"minimax tts: no audio data received\")\n\t}\n\treturn audioBuf.Bytes(), \"mp3\", nil\n}\n\n// ──────────────────────────────────────────────────────────────\n// MimoTTS — Xiaomi MiMo-V2.5-TTS implementation\n// ──────────────────────────────────────────────────────────────\n\n// MimoTTS implements TextToSpeech using the Xiaomi MiMo-V2.5-TTS API,\n// which is shaped like OpenAI chat completions: the synthesis text rides\n// on an assistant message and audio bytes come back base64-encoded inside\n// choices[0].message.audio.data.\n//\n// Docs: https://platform.xiaomimimo.com/#/docs/usage-guide/speech-synthesis\ntype MimoTTS struct {\n\tAPIKey  string\n\tBaseURL string\n\tModel   string","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/tts.go#L387-L423","documentation":"After the SSE stream ends cleanly, Synthesize checks that at least one audio byte was decoded; this error fires when the stream produced zero audio. MiniMax accepted the request (HTTP 200, status_code 0) but sent no audio chunks — often an empty/blank result (e.g. empty input text, only a status=2 trailer with no data, or an unusual stream shape).","triggerScenarios":"Input text is empty or only whitespace so MiniMax emits no audio chunks; stream ends after status=1 chunk(s) with empty audio fields; API version returns a payload shape where all audio fields are blank.","commonSituations":"Caller passes an empty string to TTS (e.g. blank commit message or summary); MiniMax degrades a response under load; mismatch between client expectations and a newer/older MiniMax stream protocol.","solutions":["Guard at the call site: skip Synthesize when the text to speak is empty or whitespace-only.","Log/inspect the raw SSE stream to confirm whether MiniMax really sent no chunks.","Upgrade/verify the client matches the current T2A v2 protocol (status 1 = incremental, status 2 = trailer).","Retry once; if MiniMax intermittently returns empty streams, add a fallback TTS provider if configured."],"exampleFix":"// before\ntts.Synthesize(ctx, text, voice)\n// after\nif strings.TrimSpace(text) == \"\" { return nil } // don't call TTS with empty text","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(text) == \"\" { return errors.New(\"tts: cannot synthesize empty text\") }","typeGuard":null,"tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"no audio data received\") {\n    // skip speaking, fall back to text-only reply, or retry once\n}","preventionTips":["Never call TTS with empty/whitespace-only input","Log the raw SSE stream when empty results occur to catch protocol drift","Add a fallback TTS provider for degraded provider responses"],"tags":["go","tts","minimax","empty-response","sse"],"backgroundTag":"empty-api-response","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}