vercel/ai · error · UnsupportedFunctionalityError

file part data type ${part.data.type}

Error message

file part data type ${part.data.type}

What it means

Mistral's chat API has no representation for this file part's data type, so formatFileUrl throws UnsupportedFunctionalityError listing the unsupported type. Only 'url' and 'data' (base64) file parts can be converted to Mistral message format.

Source

Thrown at packages/mistral/src/convert-to-mistral-chat-messages.ts:25

  MistralAssistantMessageContent,
  MistralPrompt,
} from './mistral-chat-prompt';
import {
  convertToBase64,
  getTopLevelMediaType,
  resolveFullMediaType,
} from '@ai-sdk/provider-utils';

function formatFileUrl({ part }: { part: LanguageModelV4FilePart }): string {
  if (part.data.type === 'url') {
    return part.data.url.toString();
  }

  if (part.data.type === 'data') {
    return `data:${resolveFullMediaType({ part })};base64,${convertToBase64(part.data.data)}`;
  }

  throw new UnsupportedFunctionalityError({
    functionality: `file part data type ${part.data.type}`,
  });
}

export function convertToMistralChatMessages(
  prompt: LanguageModelV4Prompt,
): MistralPrompt {
  const messages: MistralPrompt = [];

  for (let i = 0; i < prompt.length; i++) {
    const { role, content } = prompt[i];
    const isLastMessage = i === prompt.length - 1;

    switch (role) {
      case 'system': {
        messages.push({ role: 'system', content });
        break;
      }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Send file parts with url or binary data instead of the unsupported data type.
  2. Download referenced files and resend them as url or base64 data parts.
  3. Filter out unsupported file parts before constructing the prompt.
  4. Use a provider that supports the part type for that request.

Example fix

// before: provider reference
{ type: 'file', data: { type: 'reference', ... } }
// after: send binary data
{ type: 'file', mediaType: 'application/pdf', data: { type: 'data', data: pdfBytes } }
Defensive patterns

Strategy: validation

Validate before calling

function isMistralCompatibleFilePart(part: { type: string; data: { type: string } }): boolean {
  return part.type !== 'file' || ['url', 'data'].includes(part.data.type);
}
// filter before building the prompt:
const safeContent = content.filter(isMistralCompatibleFilePart);

Type guard

function isConvertibleFileData(data: unknown): data is { type: 'url'; url: string } | { type: 'data'; data: Uint8Array } {
  return (
    typeof data === 'object' && data !== null &&
    ('url' in (data as any) || 'data' in (data as any)) &&
    ['url', 'data'].includes((data as { type: string }).type)
  );
}

Try / catch

try {
  await generateText({ model: mistral(modelId), prompt });
} catch (error) {
  if (UnsupportedFunctionalityError.isInstance(error)) {
    console.warn('Unsupported part for Mistral:', error.functionality);
  } else {
    throw error;
  }
}

Prevention

When it happens

Trigger: Passing a file part whose data.type is neither 'url' nor 'data' (e.g. 'reference' or 'text') into a message sent to a Mistral chat model via streamText/generateText.

Common situations: Building prompts with provider-specific file references (from another provider's output) and sending them to Mistral; generic prompt-building code that attaches file parts of every kind.

Related errors


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