{"record":{"id":"82845a29f81b5e72","repo":"moeru-ai/airi","slug":"provider-providerid-does-not-support-generation","errorCode":null,"errorMessage":"Provider ${providerId} does not support generation","messagePattern":"Provider (.+?) does not support generation","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/stage-ui/src/stores/providers/provider.ts","lineNumber":928,"sourceCode":"      return instance as R\n    }\n    catch (error) {\n      console.error(`Error creating provider instance for ${providerId}:`, error)\n      throw error\n    }\n  }\n\n  /**\n   * Passes AIRI chat options to the provider that owns their wire representation.\n   * The cached base instance remains unchanged for consumers that do not opt in.\n   */\n  async function getChatProviderInstance(\n    providerId: string,\n    options?: ChatRequestOptions,\n  ): Promise<GenerationProvider> {\n    const provider = getGenerationProvider(await getProviderInstance(providerId))\n    if (!provider)\n      throw new Error(`Provider ${providerId} does not support generation`)\n    const reasoning = findProviderDefinition(providerId)?.capabilities?.chat?.reasoning\n    const requestOptions = options && reasoning?.modes.includes(options.reasoning) ? options : undefined\n    return { generation: model => provider.generation(model, requestOptions) }\n  }\n\n  /** Releases this renderer's transport; each window owns its own instance cache. */\n  async function disposeProviderInstance(providerId: string) {\n    const instance = providerInstanceCache.get(providerId)?.instance as { dispose?: () => Promise<void> | void } | undefined\n    // Remove ownership before awaiting cleanup so a concurrent request cannot reuse it.\n    providerInstanceCache.delete(providerId)\n    if (instance?.dispose)\n      await instance.dispose()\n  }\n\n  const availableProvidersMetadata = computedAsync<ProviderMetadata[]>(async () => {\n    // Spread-read the overrides synchronously so this re-runs when a\n    // server-driven availability flips: computedAsync uses watchEffect, which\n    // only tracks reactive reads before the first `await` — the per-provider","sourceCodeStart":910,"sourceCodeEnd":946,"githubUrl":"https://github.com/moeru-ai/airi/blob/438a067dde47aa0bdb46c2323d1fe293dc805218/packages/stage-ui/src/stores/providers/provider.ts#L910-L946","documentation":"getChatProviderInstance wraps getProviderInstance's result with getGenerationProvider; if the resulting provider object has no generation capability, the id refers to a provider that cannot perform chat/generation (e.g. an embedding-only or speech-only provider) and the store throws instead of returning a broken GenerationProvider.","triggerScenarios":"Calling getChatProviderInstance(providerId) where the provider definition for that id lacks a chat/generation capability — e.g. passing an embedding provider id where a chat provider is expected.","commonSituations":"Settings state pointing a chat model at a speech/embeddings provider; a provider type that lost chat support after an update; passing the wrong provider id from a module config (like artistry or chat stores).","solutions":["Select a provider whose capabilities include chat/generation for the model in question.","Check findProviderDefinition(providerId).capabilities.chat before calling; show a settings error instead.","Fix module configuration that points at a non-generation provider id.","Update the provider definition/adapter if the provider should support generation but its capability metadata is missing."],"exampleFix":"// before\nconst provider = await getChatProviderInstance('my-embeddings-provider')\n// after\nconst def = findProviderDefinition('my-openai-provider')\nif (!def?.capabilities?.chat)\n  throw new Error('Select a chat-capable provider')\nconst provider = await getChatProviderInstance('my-openai-provider')","handlingStrategy":"validation","validationCode":"const def = findProviderDefinition(providerId)\nif (!def?.capabilities?.chat) {\n  throw new Error(`Provider ${providerId} cannot be used for chat`)\n}","typeGuard":null,"tryCatchPattern":"try {\n  const provider = await getChatProviderInstance(providerId)\n} catch (e) {\n  if (e.message.includes('does not support generation')) ui.showProviderIncompatible(providerId)\n  else throw e\n}","preventionTips":["Filter provider pickers to providers with chat capability when configuring chat models.","Re-validate provider assignments after provider type changes or upgrades.","Distinguish provider ids by kind (chat/embeddings/speech) in stored configuration."],"tags":["providers","capability-check","llm","type-mismatch"],"backgroundTag":"unsupported-operation","analyzedSha":"438a067dde47aa0bdb46c2323d1fe293dc805218","analyzedAt":"2026-09-17T01:14:42.644Z","contentChangedAt":"2026-09-17T01:14:42.644Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}