vercel/ai · error · InvalidArgumentError

ElevenLabs realtime transcription supports audio/pcm at 8000

Error message

ElevenLabs realtime transcription supports audio/pcm at 8000, 16000, 22050, 24000, 44100, or 48000 Hz, and audio/pcmu at 8000 Hz

What it means

InvalidArgumentError thrown by getElevenLabsRealtimeAudioFormat when the input format is neither audio/pcmu at 8000 Hz nor audio/pcm at one of the supported rates (8000, 16000, 22050, 24000, 44100, 48000; defaulting to 16000 when rate is omitted). Anything else is rejected for realtime transcription.

Source

Thrown at packages/elevenlabs/src/elevenlabs-transcription-model.ts:348

  inputAudioFormat: TranscriptionModelV4StreamOptions['inputAudioFormat'],
): { audioFormat: string; sampleRate: number } {
  const type = inputAudioFormat.type.toLowerCase();
  const rate = inputAudioFormat.rate;

  if (type === 'audio/pcmu') {
    if (rate != null && rate !== 8000) {
      throw new InvalidArgumentError({
        argument: 'inputAudioFormat',
        message: 'ElevenLabs only supports audio/pcmu at 8000 Hz',
      });
    }
    return { audioFormat: 'ulaw_8000', sampleRate: 8000 };
  }

  const supportedPcmRates = [8000, 16000, 22050, 24000, 44100, 48000];
  const pcmRate = rate ?? 16000;
  if (type !== 'audio/pcm' || !supportedPcmRates.includes(pcmRate)) {
    throw new InvalidArgumentError({
      argument: 'inputAudioFormat',
      message:
        'ElevenLabs realtime transcription supports audio/pcm at 8000, 16000, 22050, 24000, 44100, or 48000 Hz, and audio/pcmu at 8000 Hz',
    });
  }

  return { audioFormat: `pcm_${pcmRate}`, sampleRate: pcmRate };
}

function buildElevenLabsRealtimeTranscriptionUrl({
  baseUrl,
  inputFormat,
  languageCode,
  modelId,
  streamingOptions,
}: {
  baseUrl: URL;
  inputFormat: string;

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Use type 'audio/pcm' with a rate from [8000, 16000, 22050, 24000, 44100, 48000].
  2. Use type 'audio/pcmu' with rate 8000 for telephony-grade audio.
  3. Transcode unsupported formats/rates to raw PCM at a supported rate before streaming.
  4. Omit the rate for PCM if 16000 Hz default is acceptable.

Example fix

// before
{ type: 'audio/mp3', rate: 32000 }
// after
{ type: 'audio/pcm', rate: 16000 }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = [8000, 16000, 22050, 24000, 44100, 48000];
function assertRealtimeAudioFormat(f: { type: string; rate?: number }) {
  const t = f.type.toLowerCase();
  const ok = t === 'audio/pcmu' || (t === 'audio/pcm' && SUPPORTED.includes(f.rate ?? 16000));
  if (!ok) throw new Error(`Unsupported realtime audio format: ${f.type} @ ${f.rate}`);
}

Type guard

function isSupportedRealtimeFormat(f: { type: string; rate?: number }): boolean {
  const t = f.type.toLowerCase();
  return t === 'audio/pcmu' || (t === 'audio/pcm' && [8000,16000,22050,24000,44100,48000].includes(f.rate ?? 16000));
}

Prevention

When it happens

Trigger: Passing inputAudioFormat like { type: 'audio/wav' }, { type: 'audio/pcm', rate: 44101 }, or { type: 'audio/mp3', rate: 48000 } to the realtime transcription inputFormat.

Common situations: Developers feed compressed formats (mp3, ogg, wav containers) or odd sample rates (e.g. 32000 Hz) that ElevenLabs realtime WebSocket endpoint does not accept.

Related errors


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