moeru-ai/airi · error · Error
MiMo TTS request failed: ${response.status} ${response.statu
Error message
MiMo TTS request failed: ${response.status} ${response.statusText} What it means
The POST to {baseUrl}/chat/completions for MiMo TTS returned a non-OK status or an empty body; the message embeds status and statusText (statusText can be empty on HTTP/2, leaving only the code). Authentication uses the api-key header, so key problems are the leading cause, followed by model and quota errors.
Source
Thrown at packages/stage-ui/src/libs/providers/providers/mimo-audio/index.ts:111
}
if (model === 'mimo-v2.5-tts-voicedesign' && !stylePrompt)
throw new Error('MiMo voice design requires a style prompt in the user message.')
const response = await fetch(new URL('chat/completions', baseUrl), {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'api-key': apiKey },
body: JSON.stringify({
model,
messages: [
{ role: 'user', content: userPrompt },
{ role: 'assistant', content: body.input ?? '' },
],
audio,
}),
})
if (!response.ok || !response.body)
throw new Error(`MiMo TTS request failed: ${response.status} ${response.statusText}`)
const data = await response.json() as {
choices?: Array<{ message?: { audio?: { data?: string } } }>
}
const audioBase64 = data.choices?.[0]?.message?.audio?.data
if (!audioBase64)
throw new Error('MiMo TTS response missing audio data')
const binary = atob(audioBase64)
const bytes = new Uint8Array(binary.length)
for (let index = 0; index < binary.length; index++)
bytes[index] = binary.charCodeAt(index)
let contentType = `audio/${format}`
if (format === 'wav')
contentType = 'audio/wav'
else if (format === 'mp3')
contentType = 'audio/mpeg'View on GitHub (pinned to 677329427f)
Solutions
- Check the embedded status: 401/403 re-enter the API key; 429 back off; 404 fix baseUrl or model
- Confirm baseUrl reaches the MiMo gateway and appends chat/completions correctly
- Verify the model id is one of the mimo-v2.5-tts family
- Inspect the request in devtools — statusText alone may be empty
Example fix
// before
headers: { 'api-key': '' } // empty key reaches the server → 401
// after
if (!apiKey?.trim()) throw new Error('MiMo API key is required')
headers: { 'Content-Type': 'application/json', 'api-key': apiKey } Defensive patterns
Strategy: try-catch
Validate before calling
if (!apiKey?.trim() || !URL.canParse(baseUrl))
throw new Error('MiMo provider is not configured') // fail before the request Try / catch
try {
const audio = await mimoSpeech(body)
}
catch (err) {
const [, status] = err.message.match(/MiMo TTS request failed: (\d+)/) ?? []
if (status === '401' || status === '403') promptForApiKey()
else if (status === '429') await backoffRetry()
} Prevention
- Require a non-empty api-key in provider settings before enabling
- Validate baseUrl with URL parsing at save time
- Keep the model allowlist aligned with the deployment
When it happens
Trigger: Missing or invalid api-key (401/403); a model id not served by this deployment (400/404); rate limit or quota (429); baseUrl pointing at a gateway route that does not proxy chat/completions (404/502).
Common situations: Key expired or revoked; environment config drifted between stages; a gateway in front of MiMo changed its routes; a deployment without audio-capable models.
Related errors
- Gemini TTS request failed: ${response.status} ${await respon
- MiMo voice clone requires a base64 audio sample in data URI
- MiMo voice design requires a style prompt in the user messag
- MiMo TTS response missing audio data
- MiMo transcription failed: ${response.status} ${response.sta
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/0fab9d12417d6fbd.
Report an issue: GitHub.