vercel/ai · error · UnsupportedFunctionalityError
'File data URLs in assistant messages are not supported' fun
Error message
'File data URLs in assistant messages are not supported' functionality not supported.
What it means
Assistant messages containing a 'file' part whose data is a URL are not convertible to Google's content format, which requires file attachments in assistant turns as inline bytes. The converter throws UnsupportedFunctionalityError when it encounters a file part with `type: 'url'` inside an assistant message.
Source
Thrown at packages/google/src/convert-to-google-messages.ts:405
}
case 'data': {
return {
inlineData: {
mimeType: part.mediaType,
data: convertToBase64(part.data.data),
},
thought: true,
thoughtSignature,
};
}
}
break;
}
case 'file': {
switch (part.data.type) {
case 'url': {
throw new UnsupportedFunctionalityError({
functionality:
'File data URLs in assistant messages are not supported',
});
}
case 'reference': {
if (isVertexLike) {
throw new UnsupportedFunctionalityError({
functionality: 'file parts with provider references',
});
}
return {
fileData: {
mimeType: part.mediaType,
fileUri: resolveProviderReference({
reference: part.data.reference,
provider: 'google',
}),View on GitHub (pinned to 69428b1f8b)
Solutions
- Convert the URL to inline base64 data before sending: fetch the file and pass `{ type: 'data', mediaType, data }`.
- Remove or downgrade the file part to plain text (e.g. include the URL as text) in assistant messages.
- Persist files as bytes/base64 rather than hosted URLs when targeting Google.
Example fix
// before
{ role: 'assistant', content: [{ type: 'file', data: { type: 'url', url: 'https://cdn/x.png' } }] }
// after
{ role: 'assistant', content: [{ type: 'file', data: { type: 'data', mediaType: 'image/png', data: base64Png } }] } Defensive patterns
Strategy: validation
Validate before calling
async function assistantFileUrlsResolved(messages) {
const parts = messages.flatMap(m => m.role === 'assistant' && Array.isArray(m.content) ? m.content : []);
return parts.every(p => p.type !== 'file' || p.data?.type !== 'url');
} Type guard
function isDataFilePart(part) {
return part?.type === 'file' && part?.data?.type === 'data' && typeof part.data.data === 'string' && typeof part.data.mediaType === 'string';
} Try / catch
try {
await streamText({ model: googleModel, messages });
} catch (e) {
if (e?.message?.includes('File data URLs in assistant messages are not supported')) {
// inline the URLs (fetch + base64) or drop those parts, then retry
} throw e;
} Prevention
- Convert hosted file URLs to inline base64 at persistence time.
- Remember: URL file parts are user-message-only on Google.
- Write a converter that normalizes histories per provider before calls.
When it happens
Trigger: An assistant message with a file part like `data: { type: 'url', url: 'https://...' }` in the prompt array passed to a Google Gemini/Vertex model via convertToGoogleMessages.
Common situations: Chat histories recorded from providers that return hosted file URLs (e.g. audio/image generation results); multi-provider agents sharing one persisted message log.
Related errors
- 'File data URLs in assistant messages are not supported' fun
- 'file parts with provider references' functionality is not s
- 'file parts with provider references' functionality not supp
- 'system messages are only supported at the beginning of the
- AI_UnsupportedFunctionalityError
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/8a31c3064b153699.
Report an issue: GitHub.