vercel/ai · error · InvalidArgumentError

DeepSeek file uploads support JPEG, PNG, GIF, and WebP image

Error message

DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. Provide a supported media type or a filename ending in .jpg, .jpeg, .png, .gif, or .webp. Received "${mediaType}".

What it means

If the mediaType is generic (e.g. 'application/octet-stream'), the provider tries to resolve the real type by sniffing the bytes or by the filename extension. When neither yields a supported image type, it throws InvalidArgumentError for argument 'mediaType', asking for a supported media type or a .jpg/.jpeg/.png/.gif/.webp filename.

Source

Thrown at packages/deepseek/src/files/deepseek-files.ts:208

  if (supportedMediaTypes.has(normalizedMediaType)) {
    return;
  }

  if (!genericMediaTypes.has(normalizedMediaType)) {
    throw new InvalidArgumentError({
      argument: 'mediaType',
      message:
        `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. ` +
        `Received unsupported media type "${mediaType}".`,
    });
  }

  if (detectedMediaType != null || hasSupportedFilenameExtension(filename)) {
    return;
  }

  throw new InvalidArgumentError({
    argument: 'mediaType',
    message:
      `DeepSeek file uploads support JPEG, PNG, GIF, and WebP images. ` +
      `Provide a supported media type or a filename ending in ` +
      `.jpg, .jpeg, .png, .gif, or .webp. Received "${mediaType}".`,
  });
}

function normalizeMediaType(mediaType: string): string {
  return mediaType.split(';', 1)[0].trim().toLowerCase();
}

function hasSupportedFilenameExtension(filename: string | undefined): boolean {
  if (filename == null) {
    return false;
  }

  const extensionSeparatorIndex = filename.lastIndexOf('.');

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Pass an explicit supported mediaType ('image/png', 'image/jpeg', 'image/gif', 'image/webp').
  2. Provide a filename ending in .jpg, .jpeg, .png, .gif, or .webp so the extension can disambiguate.
  3. Ensure the byte payload is a real image so content sniffing succeeds (empty/truncated buffers cannot be detected).

Example fix

// before
await files.upload({ data, mediaType: 'application/octet-stream', filename: 'blob' });

// after
await files.upload({ data, mediaType: 'application/octet-stream', filename: 'blob.png' });
// or better: await files.upload({ data, mediaType: 'image/png' });
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = /\.(jpe?g|png|gif|webp)$/i;
if (!SUPPORTED.test(filename ?? '') && !/^image\/(jpeg|png|gif|webp)$/.test(mediaType)) {
  throw new Error('Provide a supported image mediaType or a .jpg/.jpeg/.png/.gif/.webp filename');
}

Try / catch

import { InvalidArgumentError } from '@ai-sdk/provider';
try {
  await files.upload({ data, mediaType, filename });
} catch (e) {
  if (InvalidArgumentError.isInstance(e) && e.argument === 'mediaType') {
    // retry with explicit mediaType: 'image/png' (or correct type)
  } else throw e;
}

Prevention

When it happens

Trigger: Uploading generic-typed data where content sniffing fails (empty or ambiguous bytes) and the filename is missing or lacks a supported image extension, e.g. filename: 'blob' with mediaType: 'application/octet-stream'.

Common situations: Streaming in-memory blobs with no original filename, uploads from clients that strip filenames, or base64 payloads decoded without extension info.

Related errors


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