decolua/9router · error · Error

MiMo TTS error (${res.status})

Error message

MiMo TTS error (${res.status})

What it means

Thrown when the MiMo TTS upstream returns a non-2xx HTTP status. The handler parses the raw body as JSON (when possible) and prefers data.error.message, then rawText, then this status-code template. Any upstream rejection — auth, quota, invalid voice/model — lands here.

Source

Thrown at open-sse/handlers/ttsProviders/xiaomi-mimo.js:55

    body: JSON.stringify({
      model: modelId,
      stream: false,
      messages,
      audio: {
        format: "wav",
        voice: voiceId || DEFAULT_VOICE,
      },
    }),
  });

  const rawText = await res.text();
  let data = {};
  if (rawText) {
    try { data = JSON.parse(rawText); } catch { data = {}; }
  }

  if (!res.ok) {
    throw new Error(data?.error?.message || rawText || `MiMo TTS error (${res.status})`);
  }

  const audio = data?.choices?.[0]?.message?.audio?.data;
  if (!audio) throw new Error(data?.error?.message || "MiMo TTS returned no audio");

  return {
    base64: audio,
    format: data?.choices?.[0]?.message?.audio?.format || "wav",
  };
}

View on GitHub (pinned to 90b52e06ff)

Solutions

  1. Check the HTTP status in the message: 401 -> key, 400 -> model/voice params, 429 -> rate limit
  2. Verify the model (default mimo-v2.5-tts) and voiceId are valid for your Xiaomi account
  3. Log rawText to see the real upstream error when JSON parsing fails
  4. Retry with backoff on 429/5xx
  5. Confirm regional endpoint access for the Xiaomi API
Defensive patterns

Strategy: retry

Validate before calling

if (!credentials?.apiKey) throw new Error("MiMo TTS: missing API key");
if (typeof text !== "string" || !text.trim()) throw new Error("MiMo TTS: text required");

Type guard

function isMiMoHttpError(e) {
  return e instanceof Error && /^MiMo TTS error \(\d{3}\)$/.test(e.message);
}

Try / catch

try {
  return await synthesizeMiMo(text, model, key, style, language);
} catch (e) {
  const m = e.message.match(/MiMo TTS error \((\d{3})\)/);
  if (m && (m[1] === "429" || m[1].startsWith("5"))) return retryWithBackoff(() => synthesizeMiMo(text, model, key, style, language));
  throw e;
}

Prevention

When it happens

Trigger: MiMo API responds 401 (bad key), 400 (invalid modelId/voiceId/style/language), 429 (rate limit), or 5xx; body may or may not be JSON, hence the layered fallbacks.

Common situations: Expired Xiaomi keys, requesting a voiceId unavailable to the account, style/language parameters not accepted by the deployed MiMo version, or gateway/proxy errors returning HTML that can't be JSON-parsed.

Related errors


AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30). Data as JSON: /api/errors/05de02e5f99d584d. Report an issue: GitHub.