vercel/ai · error · UnsupportedFunctionalityError

Unsupported video mime type: ${mimeType}, expected one of: $

Error message

Unsupported video mime type: ${mimeType}, expected one of: ${Object.keys(BEDROCK_VIDEO_MIME_TYPES).join(', ')}

What it means

getAmazonBedrockVideoFormat maps a video MIME type to a Bedrock video format and throws UnsupportedFunctionalityError when it is not in BEDROCK_VIDEO_MIME_TYPES (mkv and mov). Bedrock's video input is limited to these containers.

Source

Thrown at packages/amazon-bedrock/src/convert-to-amazon-bedrock-chat-messages.ts:686

): AmazonBedrockDocumentFormat {
  const format =
    BEDROCK_DOCUMENT_MIME_TYPES[mimeType as AmazonBedrockDocumentMimeType];
  if (!format) {
    throw new UnsupportedFunctionalityError({
      functionality: `file mime type: ${mimeType}`,
      message: `Unsupported file mime type: ${mimeType}, expected one of: ${Object.keys(BEDROCK_DOCUMENT_MIME_TYPES).join(', ')}`,
    });
  }
  return format;
}

function getAmazonBedrockVideoFormat(
  mimeType: string,
): AmazonBedrockVideoFormat {
  const format =
    BEDROCK_VIDEO_MIME_TYPES[mimeType as AmazonBedrockVideoMimeType];
  if (!format) {
    throw new UnsupportedFunctionalityError({
      functionality: `video mime type: ${mimeType}`,
      message: `Unsupported video mime type: ${mimeType}, expected one of: ${Object.keys(BEDROCK_VIDEO_MIME_TYPES).join(', ')}`,
    });
  }

  return format;
}

function trimIfLast(
  isLastBlock: boolean,
  isLastMessage: boolean,
  isLastContentPart: boolean,
  text: string,
) {
  return isLastBlock && isLastMessage && isLastContentPart ? text.trim() : text;
}

type SystemBlock = {

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Remux/transcode the video to MOV (or MKV) with ffmpeg: ffmpeg -i in.mp4 -c copy out.mov (or re-encode if codecs are unsupported).
  2. Set the mediaType to video/quicktime after conversion.
  3. Check the 'expected one of' list in the error for the currently supported containers.
  4. If only a frame is needed, extract a PNG/JPEG frame and send it as an image part instead.

Example fix

// before
{ type: 'file', mediaType: 'video/mp4', data: mp4Bytes }
// after
execSync(`ffmpeg -i clip.mp4 -c copy clip.mov`);
{ type: 'file', mediaType: 'video/quicktime', data: readFileSync('clip.mov') }
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_VIDEO = ['video/x-matroska','video/quicktime'];
if (!SUPPORTED_VIDEO.includes(videoPart.mediaType)) {
  throw new Error(`Transcode ${videoPart.mediaType} to MOV/MKV before sending to Bedrock`);
}

Type guard

function isBedrockSupportedVideo(mediaType) {
  return ['video/x-matroska','video/quicktime'].includes(mediaType);
}

Try / catch

try {
  return await generateText({ model, messages });
} catch (error) {
  if (UnsupportedFunctionalityError.isInstance(error) && error.message.includes('Unsupported video mime type')) {
    console.error('Bedrock only accepts mkv/mov videos; transcode with ffmpeg first.');
  }
  throw error;
}

Prevention

When it happens

Trigger: Passing a video part with mediaType outside {video/x-matroska, video/quicktime} — most commonly video/mp4, video/webm, or video/avi.

Common situations: Most recorded and downloaded videos are MP4/WebM, so this fires frequently; developers assume MP4 is universally supported but Bedrock requires mkv or mov containers.

Related errors


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