vercel/ai · error · UnsupportedFunctionalityError
text file parts
Error message
text file parts
What it means
Mistral chat models don't accept file parts whose content is inline text (data.type === 'text'). convertToMistralChatMessages throws UnsupportedFunctionalityError for these parts.
Source
Thrown at packages/mistral/src/convert-to-mistral-chat-messages.ts:62
case 'user': {
messages.push({
role: 'user',
content: content.map(part => {
switch (part.type) {
case 'text': {
return { type: 'text', text: part.text };
}
case 'file': {
switch (part.data.type) {
case 'reference': {
throw new UnsupportedFunctionalityError({
functionality: 'file parts with provider references',
});
}
case 'text': {
throw new UnsupportedFunctionalityError({
functionality: 'text file parts',
});
}
case 'url':
case 'data': {
const topLevel = getTopLevelMediaType(part.mediaType);
if (topLevel === 'image') {
return {
type: 'image_url',
image_url: formatFileUrl({ part }),
};
} else {
if (part.data.type === 'data') {
const fullMediaType = resolveFullMediaType({ part });
if (fullMediaType !== 'application/pdf') {
throw new UnsupportedFunctionalityError({
functionality:View on GitHub (pinned to 69428b1f8b)
Solutions
- Inline the text content as a regular text part instead of a file part.
- If a document is required, send it as url or base64 data with a proper mediaType.
- Convert text file parts to text parts in your prompt-building code.
- Filter text file parts out for Mistral requests.
Example fix
// before
{ type: 'file', data: { type: 'text', value: 'Hello' } }
// after
{ type: 'text', text: 'Hello' } Defensive patterns
Strategy: validation
Validate before calling
function hasTextFilePart(messages: { content: unknown[] }[]): boolean {
return messages.some(m => (m.content as any[]).some(
p => p?.type === 'file' && p?.data?.type === 'text'));
}
if (hasTextFilePart(messages)) throw new Error('Convert text file parts to text parts for Mistral'); Type guard
function isTextFilePart(part: unknown): part is { type: 'file'; data: { type: 'text'; value: string } } {
return typeof part === 'object' && part !== null &&
(part as any).type === 'file' &&
(part as any).data?.type === 'text';
} Try / catch
try {
await generateText({ model: mistral(modelId), messages });
} catch (error) {
if (UnsupportedFunctionalityError.isInstance(error) &&
error.functionality.includes('text file parts')) {
// convert file parts with text data into plain text parts and retry
} else {
throw error;
}
} Prevention
- Use plain text parts for textual content instead of file parts.
- Normalize prompts per provider before dispatch.
- Add conversion tests covering every file data type you emit.
When it happens
Trigger: Sending a 'file' part with data: { type: 'text', value: '...' } in a prompt to a Mistral model.
Common situations: Trying to pass text documents as file parts generically across providers; converting prompts written for providers that accept text file parts.
Related errors
- file part data type ${part.data.type}
- file parts with provider references
- Only images and PDF file parts are supported
- Unsupported content type in assistant message: ${part.type}
- Unsupported role: ${_exhaustiveCheck}
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/317f58fd7c914ed9.
Report an issue: GitHub.