vercel/ai · error · UnsupportedFunctionalityError

streaming transcription with ${this.modelId}

Error message

streaming transcription with ${this.modelId}

What it means

The mirror case of error 805: non-realtime transcription models are served by the REST transcription endpoint and cannot be streamed. doStream checks isRealtimeTranscriptionModelId and throws UnsupportedFunctionalityError when the model id is not a realtime transcription model, since streaming output only exists for realtime models.

Source

Thrown at packages/openai/src/transcription/openai-transcription-model.ts:305

      language,
      durationInSeconds: response.duration ?? undefined,
      warnings,
      response: {
        timestamp: currentDate,
        modelId: this.modelId,
        headers: responseHeaders,
        body: rawResponse,
      },
    };
  }

  async doStream(
    options: OpenAITranscriptionStreamOptions,
  ): Promise<
    Awaited<ReturnType<NonNullable<TranscriptionModelV4['doStream']>>>
  > {
    if (!isRealtimeTranscriptionModelId(this.modelId)) {
      throw new UnsupportedFunctionalityError({
        functionality: `streaming transcription with ${this.modelId}`,
      });
    }

    const currentDate = this.config._internal?.currentDate?.() ?? new Date();
    const openAIOptions = await parseProviderOptions({
      provider: 'openai',
      providerOptions: options.providerOptions,
      schema: openAITranscriptionModelOptions,
    });
    const warnings: SharedV4Warning[] = [];

    // options that only apply to the REST transcription endpoint
    // (checked on the raw options because some have schema defaults):
    const rawOpenAIOptions = options.providerOptions?.openai ?? {};
    for (const option of [
      'include',
      'prompt',

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Use a realtime transcription model id with the streaming API
  2. Use the non-streaming transcribe() API with REST transcription models
  3. Check isRealtimeTranscriptionModelId (or your own branch) before choosing doStream vs doGenerate

Example fix

// before
streamTranscribe({ model: openai.transcription('whisper-1'), audio })
// after
const { text } = await transcribe({ model: openai.transcription('whisper-1'), audio })
Defensive patterns

Strategy: type-guard

Validate before calling

if (!isRealtimeTranscriptionModelId(modelId)) {
  // use non-streaming transcribe() instead of streamTranscribe
}

Type guard

function supportsStreamingTranscription(modelId: string): boolean {
  return isRealtimeTranscriptionModelId(modelId);
}

Try / catch

try {
  result = await streamTranscribe({ model, audio });
} catch (e) {
  if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('streaming transcription')) {
    // fall back to non-streaming transcribe() for this model
  } else throw e;
}

Prevention

When it happens

Trigger: Calling streamTranscribe/doStream on OpenAITranscriptionModel with a non-realtime model id such as 'whisper-1' or 'gpt-4o-transcribe'.

Common situations: Assuming all transcription models support streaming; copying a streaming example and changing only the model id to a REST-only model; generic abstraction layers that always call doStream.

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/b41e7029315971d5. Report an issue: GitHub.