moeru-ai/airi · error · Error

Failed to initialize speech provider

Error message

Failed to initialize speech provider

What it means

Thrown by the MiMo audio speech playground when `getProviderInstance<SpeechProvider<string>>(providerId)` resolves falsy. The page loads models and voices on mount, but building the provider itself depends on the persisted MiMo config (API key). The store's own failures throw distinct errors ('Provider credentials ... not found' / 'Provider definition ... not found'), so this branch means the MiMo factory completed but returned `undefined` — a runtime contract violation triggered by incomplete config such as a blank key.

Source

Thrown at packages/stage-pages/src/pages/settings/providers/speech/mimo-audio-speech.vue:128

const apiKeyConfigured = computed(() => !!providers.value[providerId]?.apiKey)

onMounted(async () => {
  ensureProviderConfig()

  if (!config.value?.model) {
    model.value = defaultModel
  }

  await providersStore.loadModelsForConfiguredProviders()
  await providersStore.fetchModelsForProvider(providerId)
  await speechStore.loadVoicesForProvider(providerId)
})

async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean, modelId?: string) {
  const provider = await providersStore.getProviderInstance<SpeechProvider<string>>(providerId)
  if (!provider) {
    throw new Error('Failed to initialize speech provider')
  }

  const providerConfig = providerStore.getProviderConfig(providerId)
  const modelToUse = modelId || model.value || defaultModel
  const requestConfig = {
    ...providerConfig,
    ...defaultVoiceSettings,
    stylePrompt: stylePrompt.value,
    voiceSample: voiceSample.value,
  }

  if (modelToUse === 'mimo-v2.5-tts-voiceclone' && !voiceSample.value.trim()) {
    throw new Error('Voice clone model requires a base64 audio sample in data URI format.')
  }

  const voiceToUse = modelToUse === 'mimo-v2.5-tts-voiceclone'
    ? voiceSample.value.trim()
    : voiceId || (config.value?.voice || defaultVoice)

View on GitHub (pinned to 677329427f)

Solutions

  1. Save a valid MiMo API key in the provider settings and confirm validation passes.
  2. Reload the playground after saving so `getProviderInstance` rebuilds the instance.
  3. Read the console: the store logs `Error creating provider instance for ...` right before this throw when the factory itself throws; absence of that log points to a silent undefined return.
  4. Verify the saved model selection is one of the fetched MiMo models (voiceclone prerequisites are validated separately).
  5. Report persistent falsy results with valid credentials as a factory bug.

Example fix

// before
const provider = await providersStore.getProviderInstance<SpeechProvider<string>>(providerId)
if (!provider)
  throw new Error('Failed to initialize speech provider')

// after
const config = providerStore.getProviderConfig(providerId)
if (!config?.apiKey?.trim())
  throw new Error('MiMo API key is empty. Save it in provider settings first.')
const provider = await providersStore.getProviderInstance<SpeechProvider<string>>(providerId)
if (!provider || typeof provider.speech !== 'function')
  throw new Error('MiMo factory returned no usable instance — check config and console logs')
Defensive patterns

Strategy: validation

Validate before calling

const apiKeyConfigured = computed(() => !!providers.value[providerId]?.apiKey?.trim())
if (!apiKeyConfigured.value)
  throw new Error('Save a MiMo API key before generating speech')

Type guard

function isSpeechProvider(v: unknown): v is SpeechProvider<string> {
  return typeof v === 'object' && v !== null && typeof (v as SpeechProvider<string>).speech === 'function'
}

Try / catch

try { const provider = await providersStore.getProviderInstance<SpeechProvider<string>>(providerId) }
catch (error) { showError(errorMessageFrom(error)) }

Prevention

When it happens

Trigger: Clicking Generate before the MiMo API key is saved; key saved as empty/whitespace string so the config object passes the store's presence check while the factory declines; generating during the onMounted model fetch while credentials were never entered.

Common situations: User expects the default model fallback (`modelToUse` falls back to `defaultModel`) to also cover auth; key expired/revoked and re-entered without saving; environment where the MiMo endpoint requires additional config the factory validates silently.

Related errors


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