{"record":{"id":"eda7489a18c48fbb","repo":"vercel/ai","slug":"fish-audio-does-not-provide-embedding-models","errorCode":null,"errorMessage":"Fish Audio does not provide embedding models","messagePattern":"Fish Audio does not provide embedding models","errorType":"exception","errorClass":"NoSuchModelError","httpStatus":null,"severity":"error","filePath":"packages/fish-audio/src/fish-audio-provider.ts","lineNumber":141,"sourceCode":"  };\n\n  provider.specificationVersion = 'v4' as const;\n  provider.speech = createSpeechModel;\n  provider.speechModel = createSpeechModel;\n  provider.transcription = createTranscriptionModel;\n  provider.transcriptionModel = createTranscriptionModel;\n\n  // Required ProviderV4 methods that are not supported\n  provider.languageModel = (modelId: string) => {\n    throw new NoSuchModelError({\n      modelId,\n      modelType: 'languageModel',\n      message: 'Fish Audio does not provide language models',\n    });\n  };\n\n  provider.embeddingModel = (modelId: string) => {\n    throw new NoSuchModelError({\n      modelId,\n      modelType: 'embeddingModel',\n      message: 'Fish Audio does not provide embedding models',\n    });\n  };\n  provider.textEmbeddingModel = provider.embeddingModel;\n\n  provider.imageModel = (modelId: string) => {\n    throw new NoSuchModelError({\n      modelId,\n      modelType: 'imageModel',\n      message: 'Fish Audio does not provide image models',\n    });\n  };\n\n  return provider as FishAudioProvider;\n}\n","sourceCodeStart":123,"sourceCodeEnd":159,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/fish-audio/src/fish-audio-provider.ts#L123-L159","documentation":"The Fish Audio provider's `embeddingModel` (and its alias `textEmbeddingModel`) always throws `NoSuchModelError` because Fish Audio offers no embedding capability. This stub exists to satisfy the ProviderV4 interface while giving callers a clear explanation.","triggerScenarios":"Calling `fishAudio.embeddingModel('id')`, `fishAudio.textEmbeddingModel('id')`, or passing the fishAudio provider to embed/embedMany.","commonSituations":"Building a provider-agnostic embed pipeline and substituting fishAudio; assuming all AI SDK providers support embeddings; dynamic provider selection that doesn't check capabilities.","solutions":["Use an embedding-capable provider (e.g. @ai-sdk/openai, @ai-sdk/amazon-bedrock) for embed/embedMany","Restrict fishAudio usage to speech and transcription features","Add capability checks before dynamically choosing a provider for embeddings"],"exampleFix":"// before\nconst model = fishAudio.textEmbeddingModel('default');\nawait embed({ model, value: 'text' });\n// after\nconst model = openai.textEmbeddingModel('text-embedding-3-small');\nawait embed({ model, value: 'text' });","handlingStrategy":"validation","validationCode":"// never route embed/embedMany to fishAudio; keep an allowlist of embedding providers\nconst EMBEDDING_PROVIDERS = new Set(['openai', 'amazon-bedrock', 'google', 'mistral']);\nif (!EMBEDDING_PROVIDERS.has(providerName)) throw new Error(`${providerName} does not support embeddings`);","typeGuard":"function isNoSuchModelError(e: unknown): e is NoSuchModelError {\n  return NoSuchModelError.isInstance(e);\n}","tryCatchPattern":"try {\n  return await embed({ model: fishAudio.textEmbeddingModel('x'), value });\n} catch (e) {\n  if (NoSuchModelError.isInstance(e) && e.modelType === 'embeddingModel') {\n    return embed({ model: openai.textEmbeddingModel('text-embedding-3-small'), value });\n  }\n  throw e;\n}","preventionTips":["Maintain a capability map (provider -> supported model types) for dynamic routing","Never pass fishAudio to embed/embedMany","Write unit tests asserting which provider each model type uses"],"tags":["unsupported-model-type","provider-api","embeddings","fish-audio"],"backgroundTag":"unsupported-model-type","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}