vercel/ai · error · UnsupportedFunctionalityError
text file parts
Error message
text file parts
What it means
Perplexity only accepts binary/remote file content (e.g. PDFs by URL or data), not files whose payload is textual content carried inline. convertToPerplexityMessages throws UnsupportedFunctionalityError for file parts with data.type === 'text' since there is no corresponding Perplexity message field.
Source
Thrown at packages/perplexity/src/convert-to-perplexity-messages.ts:54
const messageContent = content
.map((part, index) => {
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 topLevelMediaType = getTopLevelMediaType(
part.mediaType,
);
if (topLevelMediaType === 'application') {
const fullMediaType = resolveFullMediaType({ part });
if (fullMediaType !== 'application/pdf') {
throw new UnsupportedFunctionalityError({
functionality: `file part media type ${fullMediaType}`,
});
}
View on GitHub (pinned to 69428b1f8b)
Solutions
- Send the content as a normal text part instead of a file part
- Upload/host the document and pass it as a URL file part (PDF)
- Convert the text into a base64 data part with the proper media type if the content is a supported binary format
Example fix
// before
{ type: 'file', data: { type: 'text', value: 'document text...' }, mediaType: 'application/pdf' }
// after
{ type: 'text', text: 'document text...' } Defensive patterns
Strategy: validation
Validate before calling
for (const part of msg.content) {
if (part.type === 'file' && part.data?.type === 'text') {
throw new Error('Send textual content as a text part, not a file part (Perplexity)');
}
} Type guard
function isTextFilePart(part: { type: string; data?: { type?: string } }): boolean {
return part.type === 'file' && part.data?.type === 'text';
} Try / catch
try {
await generateText({ model: perplexity('sonar-pro'), messages });
} catch (e) {
if (UnsupportedFunctionalityError.isInstance(e) && e.message.includes('text file parts')) {
// convert those parts to plain text parts and retry
} else throw e;
} Prevention
- Use text parts for textual content; reserve file parts for binary documents
- Review document-ingestion pipelines that wrap extracted text in file parts
- Add a preprocessing step that normalizes file parts before provider dispatch
When it happens
Trigger: Constructing a file part with data as plain text/string content ({ type: 'text', ... }) in a message sent to a Perplexity chat model.
Common situations: Passing extracted text of a document as a 'file' part instead of as a text part; generic document pipelines that build file parts with inline text payloads regardless of provider.
Related errors
- file parts with provider references
- file part media type ${fullMediaType}
- AI_UnsupportedFunctionalityError
- file parts with provider references
- File URL data
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/1ee64efb30f32886.
Report an issue: GitHub.