{"record":{"id":"f43a641f06f3faaa","repo":"decolua/9router","slug":"xiaomi-mimo-api-key-required","errorCode":null,"errorMessage":"xiaomi-mimo API key required","messagePattern":"xiaomi-mimo API key required","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"open-sse/handlers/ttsProviders/xiaomi-mimo.js","lineNumber":13,"sourceCode":"// Xiaomi MiMo TTS — via OpenAI-compatible chat completions (non-streaming).\n// Docs: https://mimo.mi.com/docs/zh-CN/quick-start/usage-guide/audio/speech-synthesis-v2.5\n// Message contract: target text in `role: assistant` content, style/voice\n// instructions in `role: user` content. Voice is selected via the top-level\n// `audio.voice` field (NOT embedded in the model name).\nimport { parseModelVoice } from \"./_base.js\";\n\nconst DEFAULT_MODEL = \"mimo-v2.5-tts\";\nconst DEFAULT_VOICE = \"mimo_default\";\n\nexport default {\n  synthesize(text, model, credentials, responseFormat, { style, language } = {}) {\n    if (!credentials?.apiKey) throw new Error(\"xiaomi-mimo API key required\");\n    return synthesizeMiMo(text, model, credentials.apiKey, style, language);\n  },\n};\n\nexport async function synthesizeMiMo(text, model, apiKey, style, language) {\n  const { modelId, voiceId } = parseModelVoice(model, DEFAULT_MODEL, DEFAULT_VOICE, [DEFAULT_MODEL]);\n\n  // Language and style are soft instructions → prepend as a role:user message.\n  // MiMo auto-detects the spoken language of the text; the hint only nudges it\n  // (e.g. \"Speak in English.\") and is independent of the chosen voice.\n  const instructions = [];\n  if (language) instructions.push(`Speak in ${language}.`);\n  if (style) instructions.push(style);\n\n  const messages = [{ role: \"assistant\", content: text }];\n  if (instructions.length) messages.unshift({ role: \"user\", content: instructions.join(\" \") });\n\n  const res = await fetch(\"https://api.xiaomimimo.com/v1/chat/completions\", {","sourceCodeStart":1,"sourceCodeEnd":31,"githubUrl":"https://github.com/decolua/9router/blob/90b52e06ffd666b7929554211474d01588f6b1f8/open-sse/handlers/ttsProviders/xiaomi-mimo.js#L1-L31","documentation":"The Xiaomi MiMo TTS provider's synthesize() guard requires credentials.apiKey; without it it throws synchronously before calling synthesizeMiMo. Pure local configuration check — no network involved.","triggerScenarios":"Calling TTS routed to xiaomi-mimo with no Xiaomi API key stored in 9Router credentials, or a credential entry with an empty/undefined apiKey.","commonSituations":"MiMo added as a model but key never configured; key revoked/expired on the Xiaomi open platform; wrong credentials object passed by the caller.","solutions":["Configure a Xiaomi MiMo API key in the 9Router provider credentials","Verify the key is valid on the Xiaomi open platform console","Restart the gateway so credential caches reload","Switch to a TTS provider that has credentials configured"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if (!credentials?.apiKey) throw new Error(\"Configure a Xiaomi MiMo API key before using xiaomi-mimo TTS\");","typeGuard":"function hasMiMoKey(c) {\n  return typeof c?.apiKey === \"string\" && c.apiKey.trim().length > 0;\n}","tryCatchPattern":"try {\n  await mimoTts.synthesize(text, model, creds);\n} catch (e) {\n  if (e.message === \"xiaomi-mimo API key required\") {\n    notifyUser(\"Add a Xiaomi MiMo API key in provider settings\");\n  } else throw e;\n}","preventionTips":["Preflight-check enabled TTS providers for configured keys at startup","Renew Xiaomi keys before expiry and update the store","Avoid cross-assigning credentials between providers","Expose per-provider credential status in the dashboard"],"tags":["tts","xiaomi","mimo","api-key","missing-credentials"],"backgroundTag":"missing-api-key","analyzedSha":"90b52e06ffd666b7929554211474d01588f6b1f8","analyzedAt":"2026-08-30T21:05:45.952Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}