moeru-ai/airi · error · Error

Provider credentials for ${providerId} not found

Error message

Provider credentials for ${providerId} not found

What it means

getProviderInstance is the single construction path for providers. It reads saved credentials from providerCredentials; when none exist and the definition does not declare requiresCredentials === false (and it is not the special-cased 'browser-web-speech-api'), it throws this before ever calling createProvider.

Source

Thrown at packages/stage-ui/src/stores/providers/provider.ts:820

  >(providerId: string): Promise<R> {
    await waitForProviderMetadata()
    const cached = providerInstanceCache.get(providerId) as R | undefined
    if (cached)
      return cached

    const definition = getProviderDefinition(providerId)

    // Providers that don't require credentials use empty config
    let config = providerCredentials.value[providerId]
    const noCredentials = definition.requiresCredentials === false || providerId === 'browser-web-speech-api'
    if (!config && noCredentials) {
      config = getDefaultProviderConfig(providerId) || {}
      const definitionId = getProviderDefinitionId(providerId)
      providerConfigStore.ensureProvider(providerId, definitionId, config)
    }

    if (!config && !noCredentials)
      throw new Error(`Provider credentials for ${providerId} not found`)

    try {
      const instance = await definition.createProvider(config || {})
      providerInstanceCache.set(providerId, instance)
      return instance as R
    }
    catch (error) {
      console.error(`Error creating provider instance for ${providerId}:`, error)
      throw error
    }
  }

  /**
   * Passes AIRI chat options to the provider that owns their wire representation.
   * The cached base instance remains unchanged for consumers that do not opt in.
   */
  async function getChatProviderInstance(
    providerId: string,

View on GitHub (pinned to f679616c34)

Solutions

  1. Open Settings > Providers, save credentials for the provider, and retry.
  2. Verify the providerId string matches the definition id exactly (case-sensitive).
  3. If the provider genuinely needs no credentials, add requiresCredentials: false to its definition.
  4. In tests, seed providerCredentials or use the credential-less 'browser-web-speech-api' provider.

Example fix

// before
const provider = await providersStore.getProviderInstance('openai')

// after
if (!providerCredentials.value['openai'] && getProviderDefinition('openai').requiresCredentials !== false) {
  throw new Error('Save the OpenAI API key in Settings > Providers before using it')
}
const provider = await providersStore.getProviderInstance('openai')
Defensive patterns

Strategy: validation

Validate before calling

const needsCredentials = definition.requiresCredentials !== false && providerId !== 'browser-web-speech-api'
if (needsCredentials && !providerCredentials.value[providerId]) {
  // route the user to provider settings instead of calling getProviderInstance
}

Try / catch

try {
  const instance = await providersStore.getProviderInstance(providerId)
}
catch (e) {
  if (errorMessageFrom(e)?.includes('credentials'))
    openProviderSettings(providerId)
  else
    throw e
}

Prevention

When it happens

Trigger: Awaiting providersStore.getProviderInstance(id) for a provider whose API key/config was never saved; a providerId typo that matches no saved credentials entry; credentials wiped by logout or storage clear while the provider stayed selected.

Common situations: Fresh install where a provider is selected before credentials exist; tests instantiating the real store without seeding providerCredentials; switching devices; provider renamed so the old id has no credentials entry.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of moeru-ai/airi@f679616c34 (2026-08-28). Data as JSON: /api/errors/261f66ddfb0a2a46. Report an issue: GitHub.