moeru-ai/airi · error · Error

MiMo TTS response missing audio data

Error message

MiMo TTS response missing audio data

What it means

The MiMo chat/completions call returned HTTP OK, but choices[0].message.audio.data is absent, so the provider refuses rather than running atob on nothing. A 200 without audio means the model answered in text or the gateway stripped the audio field — typically a model id that is not an audio-output variant or content that skipped synthesis.

Source

Thrown at packages/stage-ui/src/libs/providers/providers/mimo-audio/index.ts:118

          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'

        return new Response(bytes.buffer, {
          status: 200,
          headers: { 'Content-Type': contentType },
        })
      },
    }),

View on GitHub (pinned to 677329427f)

Solutions

  1. Confirm the model id is a tts variant (mimo-v2.5-tts, -voiceclone, -voicedesign)
  2. Log the full choices[0].message to see whether text came back instead of audio
  3. Check the gateway version and docs for the expected audio response shape
  4. Retry with the plain tts model and a named voice to isolate the cause

Example fix

// before
model: 'mimo-v2.5-chat' // text model → 200 with no audio → throw

// after
model: 'mimo-v2.5-tts' // audio-capable variant returns choices[0].message.audio.data
Defensive patterns

Strategy: try-catch

Validate before calling

const TTS_MODELS = new Set(['mimo-v2.5-tts', 'mimo-v2.5-tts-voiceclone', 'mimo-v2.5-tts-voicedesign'])
if (!TTS_MODELS.has(model))
  throw new Error(`Model ${model} does not produce audio`)

Try / catch

try {
  const wav = await synthesize(text, { model })
}
catch (err) {
  if (err.message.includes('missing audio data'))
    console.warn('MiMo returned text-only:', lastChoicesMessage)
}

Prevention

When it happens

Trigger: Model id routed to a text-only mimo variant; a gateway version returning audio under a different response shape; content policy producing a textual refusal; the audio field not applied because the model ignored it.

Common situations: Deployment updated and renamed tts models; request built with a chat model id by mistake; an intermediate proxy normalizing the response and dropping the audio key.

Related errors


AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18). Data as JSON: /api/errors/3d5188ed3e608017. Report an issue: GitHub.