vercel/ai · error · UnsupportedFunctionalityError
non-streaming transcription with ${this.modelId}
Error message
non-streaming transcription with ${this.modelId} What it means
Realtime transcription models (detected via isRealtimeTranscriptionModelId, e.g. gpt-4o-transcribe realtime variants) only support streaming output. Calling doGenerate on OpenAITranscriptionModel with such a model id throws UnsupportedFunctionalityError because there is no non-streaming REST endpoint for it.
Source
Thrown at packages/openai/src/transcription/openai-transcription-model.ts:241
}
} else {
formData.append(key, String(value));
}
}
}
}
return {
formData,
warnings,
};
}
async doGenerate(
options: OpenAITranscriptionCallOptions,
): Promise<Awaited<ReturnType<TranscriptionModelV4['doGenerate']>>> {
if (isRealtimeTranscriptionModelId(this.modelId)) {
throw new UnsupportedFunctionalityError({
functionality: `non-streaming transcription with ${this.modelId}`,
});
}
const currentDate = this.config._internal?.currentDate?.() ?? new Date();
const { formData, warnings } = await this.getArgs(options);
const {
value: response,
responseHeaders,
rawValue: rawResponse,
} = await postFormDataToApi({
url: this.config.url({
path: '/audio/transcriptions',
modelId: this.modelId,
}),
headers: combineHeaders(this.config.headers?.(), options.headers),
formData,View on GitHub (pinned to 69428b1f8b)
Solutions
- Use the streaming API (streamTranscription/doStream) with realtime transcription models
- Switch the model id to a REST-supported transcription model (e.g. whisper-1, gpt-4o-transcribe) for non-streaming use
- Branch your code on the model id to select the right call style
Example fix
// before
await transcribe({ model: openai.transcription('gpt-4o-mini-transcribe-realtime'), audio })
// after
const result = streamTranscribe({ model: openai.transcription('gpt-4o-mini-transcribe-realtime'), audio }) Defensive patterns
Strategy: type-guard
Validate before calling
import { isRealtimeTranscriptionModelId } from '@ai-sdk/openai'; // or local copy
if (isRealtimeTranscriptionModelId(modelId)) {
// use streaming API instead of transcribe()
} Type guard
function supportsNonStreamingTranscription(modelId: string): boolean {
return !isRealtimeTranscriptionModelId(modelId);
} Try / catch
try {
result = await transcribe({ model, audio });
} catch (e) {
if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('non-streaming transcription')) {
// switch to the streaming transcription API for this model
} else throw e;
} Prevention
- Keep a mapping of which transcription models support REST vs realtime
- Route realtime model ids to streamTranscribe in your abstraction layer
- Read the model's provider docs before switching model ids in shared config
When it happens
Trigger: Calling generateText-style transcription (transcribe(...)/doGenerate) with a realtime transcription model id; switching a model id string from a REST transcription model to a realtime one without changing the call to its streaming API.
Common situations: Swapping model ids in config (e.g. 'whisper-1' -> realtime model) while keeping the non-streaming transcribe() call; templated pipelines that always use doGenerate; misunderstanding that realtime models can also do one-shot transcription.
Related errors
- streaming transcription with ${this.modelId}
- streaming transcription with ${this.modelId}
- 'element streams in no-schema mode' functionality not suppor
- 'element streams in object mode' functionality not supported
- 'element streams in enum mode' functionality not supported.
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/12333528768028e0.
Report an issue: GitHub.