moeru-ai/airi · error · Error
Failed to initialize speech provider
Error message
Failed to initialize speech provider
What it means
Thrown by the ElevenLabs speech playground when `getProviderInstance('elevenlabs')` resolves falsy. The ElevenLabs definition (packages/stage-ui/src/libs/providers/providers/elevenlabs/index.ts:90) builds the instance via `createUnElevenLabs(config.apiKey.trim(), config.baseUrl ?? 'https://unspeech.hyp3r.link/v1/')`; although the static type says non-nullable, the underlying unspeech factory can yield `undefined` when the key is blank, and this page guard converts that into an explicit error before `speechStore.speech()` is called with a dead provider.
Source
Thrown at packages/stage-pages/src/pages/settings/providers/speech/elevenlabs.vue:55
const speechStore = useSpeechStore()
const providersStore = useProviderStore()
const providerStore = useProviderConfigStore()
const { configs: providers } = storeToRefs(providerStore)
const { t } = useI18n()
// Check if API key is configured
const apiKeyConfigured = computed(() => !!providers.value[providerId]?.apiKey)
// Get available voices for ElevenLabs
const availableVoices = computed(() => {
return speechStore.availableVoices[providerId] || []
})
// Generate speech with ElevenLabs-specific parameters
async function handleGenerateSpeech(input: string, voiceId: string, _useSSML: boolean) {
const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>
if (!provider) {
throw new Error('Failed to initialize speech provider')
}
// Get provider configuration
const providerConfig = providerStore.getProviderConfig(providerId)
// Get model from configuration or use default
const model = providerConfig.model as string | undefined || defaultModel
// ElevenLabs doesn't need SSML conversion, but if SSML is provided, use it directly
return await speechStore.speech(
provider,
model,
input,
voiceId,
{
...providerConfig,
...defaultVoiceSettings,
},View on GitHub (pinned to 677329427f)
Solutions
- Save a valid ElevenLabs API key in Settings → Providers → ElevenLabs and pass the built-in validators (they require apiKey and an absolute baseUrl with trailing slash when overridden).
- Reload the settings page after saving so `getProviderInstance` builds from current config.
- Inspect console output for `Error creating provider instance for elevenlabs:` preceding this throw.
- If a custom baseUrl is set, confirm it is absolute with a trailing slash — the validator flags that separately but the factory can also fail on it.
- Treat persistent falsy results with a valid key as a factory bug (contract violation) and report it upstream.
Example fix
// before
const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>
if (!provider)
throw new Error('Failed to initialize speech provider')
// after
const config = providerStore.getProviderConfig(providerId)
if (!config?.apiKey?.trim())
throw new Error('ElevenLabs API key is empty. Save it in provider settings first.')
const provider = await providersStore.getProviderInstance(providerId) as SpeechProviderWithExtraOptions<string, UnElevenLabsOptions>
if (!provider || typeof provider.speech !== 'function')
throw new Error('ElevenLabs factory returned no usable instance — check key/baseUrl and console logs') Defensive patterns
Strategy: validation
Validate before calling
const canGenerate = computed(() => {
const c = providers.value[providerId]
return !!c?.apiKey?.trim() && (!c?.baseUrl || /^https?:\/\/.+\/$/.test(c.baseUrl.trim()))
}) Type guard
function isSpeechProvider(v: unknown): v is SpeechProviderWithExtraOptions<string, UnElevenLabsOptions> {
return typeof v === 'object' && v !== null && typeof (v as SpeechProviderWithExtraOptions<string>).speech === 'function'
} Try / catch
try { const provider = await providersStore.getProviderInstance(providerId) }
catch (error) { // store-level: credentials/definition missing — surface message directly
showError(errorMessageFrom(error)) } Prevention
- Require a trimmed non-empty API key before enabling the playground.
- When overriding baseUrl, validate absolute URL with trailing slash at save time.
- Reload the page after credential changes so the cached instance rebuilds.
When it happens
Trigger: Clicking Generate with `providers.value.elevenlabs.apiKey` empty or whitespace; config saved with a key but the unspeech factory silently declining it; baseUrl left unset is fine (it falls back to the unspeech bridge) — the failing input is the missing key.
Common situations: Trying the playground before finishing provider setup; clearing the key field and saving; copy/pasting a key with quotes or spaces so `.trim()` yields an unusable credential; stale page state after revoking a key in the ElevenLabs dashboard.
Related errors
- Failed to initialize speech provider
- Failed to initialize speech provider
- Failed to initialize speech provider
- Failed to initialize speech provider
- Failed to initialize speech provider
AI-assisted analysis of moeru-ai/airi@677329427f (2026-08-18).
Data as JSON: /api/errors/1872f445f6352c51.
Report an issue: GitHub.