{"record":{"id":"59e0184a1d0de88b","repo":"moeru-ai/airi","slug":"failed-to-initialize-speech-provider-59e018","errorCode":null,"errorMessage":"Failed to initialize speech provider","messagePattern":"Failed to initialize speech provider","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/stage-pages/src/pages/settings/providers/speech/player2-speech.vue","lineNumber":32,"sourceCode":"import { computed, onMounted, ref, watch } from 'vue'\nimport { useI18n } from 'vue-i18n'\n\nconst providerId = 'player2-speech'\nconst defaultModel = 'v1'\nconst speedRatio = ref<number>(1.0)\nconst speechStore = useSpeechStore()\nconst providersStore = useProviderStore()\nconst providerStore = useProviderConfigStore()\nconst { t } = useI18n()\n// Get available voices for Player2\nconst availableVoices = computed(() => {\n  return speechStore.availableVoices[providerId] || []\n})\n// Generate speech with Player2-specific parameters\nasync function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) {\n  const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>\n  if (!provider) {\n    throw new Error('Failed to initialize speech provider')\n  }\n  // Get provider configuration\n  const providerConfig = providerStore.getProviderConfig(providerId)\n  // Get model from configuration or use default\n  const model = providerConfig.model as string | undefined || defaultModel\n  // Player2 doesn't need SSML conversion, but if SSML is provided, use it directly\n  return await speechStore.speech(\n    provider,\n    model,\n    input,\n    voiceId,\n    {\n      ...providerConfig,\n    },\n  )\n}\nconst hasPlayer2 = ref(true)\nonMounted(async () => {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/moeru-ai/airi/blob/677329427f32468c74b17f3ec47eeca4e05bec65/packages/stage-pages/src/pages/settings/providers/speech/player2-speech.vue#L14-L50","documentation":"Thrown by the Player2 speech playground when `getProviderInstance(providerId)` resolves falsy. Player2 is a local speech engine: unlike cloud providers it does not hinge on an API key, so a falsy build usually means the local runtime/config needed by the Player2 factory was not usable at construction time. The page even reuses the ElevenLabs option types and comments (copy-paste), but the failure mode is the same contract violation: `createProvider` returned undefined where the type promises an instance.","triggerScenarios":"Clicking Generate before the local Player2 engine/config is set up in provider settings; blank required local config fields; environments where the Player2 runtime (local inference) is unavailable so the factory declines.","commonSituations":"First use of a local provider assuming zero configuration; desktop vs web build differences in local runtime availability; stale empty config object left from an aborted setup; factory silently declining on malformed values instead of throwing.","solutions":["Complete the Player2 provider configuration in Settings → Providers (fill whatever local endpoint/model fields it exposes) and save.","Confirm the local Player2 runtime is installed/running for your build (web vs desktop).","Reload the playground after saving to rebuild the instance.","Check console for `Error creating provider instance for ...` for the underlying decline reason.","Report it if configuration is complete and the factory still returns nothing."],"exampleFix":"// before\nconst provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>\nif (!provider)\n  throw new Error('Failed to initialize speech provider')\n\n// after\nconst provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>\nif (!provider || typeof provider.speech !== 'function')\n  throw new Error('Player2 local engine returned no usable instance — check local runtime config and console logs')","handlingStrategy":"validation","validationCode":"const configReady = computed(() => {\n  const c = providerStore.getProviderConfig(providerId)\n  return !!c && Object.values(c).some(v => typeof v === 'string' && v.trim())\n})\nif (!configReady.value)\n  throw new Error('Complete the Player2 local engine configuration first')","typeGuard":"function isSpeechProvider(v: unknown): v is SpeechProviderWithExtraOptions<string> {\n  return typeof v === 'object' && v !== null && typeof (v as SpeechProviderWithExtraOptions<string>).speech === 'function'\n}","tryCatchPattern":"try { const provider = await providersStore.getProviderInstance(providerId) }\ncatch (error) { showError(errorMessageFrom(error)) }","preventionTips":["Verify local runtime availability for your build (web vs desktop) before offering the playground.","Do not assume credential-less means config-less.","Report silent undefined returns — local factories should throw with the missing prerequisite."],"tags":["speech","provider","initialization","local","player2"],"backgroundTag":"provider-instance-undefined","analyzedSha":"677329427f32468c74b17f3ec47eeca4e05bec65","analyzedAt":"2026-08-18T17:29:58.153Z","schemaVersion":2},"datasetVersion":"2026-08-23T16:17:53.355Z"}