{"record":{"id":"96ac1e52f2cb575e","repo":"moeru-ai/airi","slug":"failed-to-initialize-speech-provider-96ac1e","errorCode":null,"errorMessage":"Failed to initialize speech provider","messagePattern":"Failed to initialize speech provider","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/stage-pages/src/pages/settings/providers/speech/index-tts-vllm.vue","lineNumber":45,"sourceCode":"const apiKeyConfigured = true // Assuming API key is always configured as its not required\n\n// Get available voices for Index TTS provider\nconst availableVoices = computed(() => {\n  return speechStore.availableVoices[providerId] || []\n})\n\nonMounted(async () => {\n  await speechStore.loadVoicesForProvider(providerId)\n})\n\nwatch([apiKeyConfigured], async () => {\n  await speechStore.loadVoicesForProvider(providerId)\n})\n\nasync function handleGenerateSpeech(input: string, voiceId: string) {\n  const provider = await providersStore.getProviderInstance(providerId) as SpeechProvider\n  if (!provider) {\n    throw new Error('Failed to initialize speech provider')\n  }\n\n  // Get provider configuration\n  const providerConfig = providerStore.getProviderConfig(providerId)\n\n  // Get model from configuration or use default\n  const model = providerConfig.model as string | undefined || defaultModel\n\n  const options = {\n    ...providerConfig,\n  }\n\n  return await speechStore.speech(\n    provider,\n    model,\n    input,\n    voiceId,\n    options,","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-pages/src/pages/settings/providers/speech/index-tts-vllm.vue#L27-L63","documentation":"Thrown by the IndexTTS-vLLM playground when the provider factory resolves falsy. IndexTTS-vLLM is a self-hosted provider: its definition builds an instance aimed at a user-provided vLLM server baseUrl rather than a cloud API key. `getProviderInstance` only throws its own errors when the definition or the whole config is missing; reaching this guard means `createProvider(config)` returned undefined, in practice because the endpoint configuration is blank or malformed.","triggerScenarios":"Clicking Generate before saving the vLLM server URL; baseUrl saved as empty string (the onMounted `??=` defaults elsewhere intentionally keep empty strings); pointing at a URL the factory refuses (missing scheme, wrong path) so it declines instead of constructing a client.","commonSituations":"Local vLLM/IndexTTS server not started yet or moved to another port; URL pasted without `http://`; switching between remote and local deployments and leaving the field blank; assuming the provider needs no config because it is local.","solutions":["Start the IndexTTS vLLM server and save its full base URL (scheme + host + port) in the provider settings.","Verify the endpoint with a direct request (e.g. models list) before returning to the playground.","Reload the page after saving so `getProviderInstance` rebuilds from fresh config.","Check console for `Error creating provider instance for ...` with the factory's underlying reason.","Report a bug if a reachable, fully-configured endpoint still produces a falsy instance."],"exampleFix":"// before\nconst provider = await providersStore.getProviderInstance(providerId) as SpeechProvider\nif (!provider)\n  throw new Error('Failed to initialize speech provider')\n\n// after\nconst config = providerStore.getProviderConfig(providerId)\nif (!config?.baseUrl?.trim())\n  throw new Error('IndexTTS vLLM base URL is empty. Start the server and save its URL first.')\nconst provider = await providersStore.getProviderInstance(providerId) as SpeechProvider\nif (!provider || typeof provider.speech !== 'function')\n  throw new Error('IndexTTS vLLM factory returned no usable instance — check baseUrl and console logs')","handlingStrategy":"validation","validationCode":"const endpointConfigured = computed(() => {\n  const url = providers.value[providerId]?.baseUrl?.trim() ?? ''\n  return /^https?:\\/\\//.test(url)\n})\nif (!endpointConfigured.value)\n  throw new Error('Start the IndexTTS vLLM server and save its base URL first')","typeGuard":"function isSpeechProvider(v: unknown): v is SpeechProvider {\n  return typeof v === 'object' && v !== null && typeof (v as SpeechProvider).speech === 'function'\n}","tryCatchPattern":"try { const provider = await providersStore.getProviderInstance(providerId) }\ncatch (error) { showError(errorMessageFrom(error)) }","preventionTips":["Health-check the vLLM endpoint (models list) before synthesis.","Save the full URL including scheme and port.","Never leave baseUrl as an empty string when saving the provider."],"tags":["speech","provider","initialization","base-url","vllm","self-hosted"],"backgroundTag":"provider-instance-undefined","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}