{"record":{"id":"d25fbcc9fe422aac","repo":"moeru-ai/airi","slug":"minimax-tts-request-failed-response-status-r-d25fbc","errorCode":null,"errorMessage":"MiniMax TTS request failed: ${response.status} ${response.statusText}","messagePattern":"MiniMax TTS request failed: (.+?) (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/provider-inference/src/providers/cloud/minimax-speech/index.ts","lineNumber":61,"sourceCode":"              text: body.input ?? '',\n              stream: true,\n              voice_setting: {\n                voice_id: body.voice || 'English_Graceful_Lady',\n                speed: 1,\n                vol: 1,\n                pitch: 0,\n              },\n              audio_setting: {\n                sample_rate: 32000,\n                bitrate: 128000,\n                format: 'mp3',\n                channel: 1,\n              },\n            }),\n          })\n\n          if (!response.ok || !response.body)\n            throw new Error(`MiniMax TTS request failed: ${response.status} ${response.statusText}`)\n\n          // MiniMax streams SSE events that contain hex-encoded audio chunks.\n          const reader = response.body.getReader()\n          const decoder = new TextDecoder()\n          const audioChunks: Uint8Array[] = []\n          let buffer = ''\n\n          while (true) {\n            const { done, value } = await reader.read()\n            if (done)\n              break\n\n            buffer += decoder.decode(value, { stream: true })\n            const lines = buffer.split('\\n')\n            buffer = lines.pop() || ''\n            for (const line of lines) {\n              if (!line.startsWith('data:'))\n                continue","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/moeru-ai/airi/blob/f679616c34f1cf6d282c8d64264242af944b3fed/packages/provider-inference/src/providers/cloud/minimax-speech/index.ts#L43-L79","documentation":"After forwarding the TTS request to MiniMax's /v1/t2a_v2 endpoint, the provider requires an ok HTTP response with a readable stream body (MiniMax streams SSE with hex-encoded audio chunks). A non-ok status or a missing/null body produces this error — an upstream API failure.","triggerScenarios":"MiniMax returns 401 (invalid API key), 400 (invalid voice/model/text), 402 (insufficient quota/credits), 429 (rate limited), or 5xx; or the response arrives without a body (rare, e.g. some proxies or mocks).","commonSituations":"Wrong or expired MiniMax API key; voice id not enabled for the account; account out of credits; text containing unsupported characters; streaming disabled by an intermediate proxy.","solutions":["Log the response status and MiniMax's JSON error payload to identify the cause (auth, quota, or payload).","Verify the MiniMax API key and account balance/quota.","Confirm the voice and model ids are valid and enabled for your account.","Retry with backoff on 429/5xx.","Check that no proxy strips the response body; test the same request with curl."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (!apiKey) throw new Error('MiniMax API key required')\nif (!text?.trim()) throw new Error('TTS input text required')","typeGuard":null,"tryCatchPattern":"try { await tts(text) } catch (e) {\n  if (/failed: (429|5\\d\\d)/.test(e.message)) await backoffRetry()\n  else if (/401/.test(e.message)) notifyInvalidApiKey()\n  else if (/402/.test(e.message)) notifyInsufficientQuota()\n  else throw e\n}","preventionTips":["Monitor MiniMax quota/balance","Validate voice and model ids for your account","Retry on 429/5xx with backoff","Verify streaming not blocked by proxies"],"tags":["tts","network","http","upstream-api"],"backgroundTag":"upstream-api-error","analyzedSha":"f679616c34f1cf6d282c8d64264242af944b3fed","analyzedAt":"2026-09-08T13:18:15.005Z","contentChangedAt":"2026-09-08T13:18:15.005Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}