{"record":{"id":"6d555a090b193178","repo":"vercel/ai","slug":"text-file-parts-functionality-not-supported-6d555a","errorCode":null,"errorMessage":"'text file parts' functionality not supported.","messagePattern":"'text file parts' functionality not supported\\.","errorType":"exception","errorClass":"UnsupportedFunctionalityError","httpStatus":null,"severity":"error","filePath":"packages/xai/src/convert-to-xai-chat-messages.ts","lineNumber":61,"sourceCode":"              userContent.push({ type: 'text', text: part.text });\n              break;\n            }\n            case 'file': {\n              switch (part.data.type) {\n                case 'reference': {\n                  userContent.push({\n                    type: 'file',\n                    file: {\n                      file_id: resolveProviderReference({\n                        reference: part.data.reference,\n                        provider: 'xai',\n                      }),\n                    },\n                  });\n                  break;\n                }\n                case 'text': {\n                  throw new UnsupportedFunctionalityError({\n                    functionality: 'text file parts',\n                  });\n                }\n                case 'url':\n                case 'data': {\n                  if (getTopLevelMediaType(part.mediaType) === 'image') {\n                    const filePartOptions = await parseProviderOptions({\n                      provider: 'xai',\n                      providerOptions: part.providerOptions,\n                      schema: xaiFilePartProviderOptions,\n                    });\n\n                    userContent.push({\n                      type: 'image_url',\n                      image_url: {\n                        url:\n                          part.data.type === 'url'\n                            ? part.data.url.toString()","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/vercel/ai/blob/69428b1f8b037e4d118fb4853428d5c4e620493c/packages/xai/src/convert-to-xai-chat-messages.ts#L43-L79","documentation":"convertToXaiChatMessages maps AI SDK file parts to xAI's chat format. xAI's chat API supports image file parts but not text file parts, so a file part with a text media type throws UnsupportedFunctionalityError with the message 'text file parts' functionality not supported.","triggerScenarios":"Passing a message containing a FilePart whose mediaType is a text type (e.g. text/plain) to a model from @ai-sdk/xai via generateText/streamText.","commonSituations":"Sending extracted PDF text or .txt/.csv attachments as file parts; generic file-upload UI forwarding all attachments to the model; code written for another provider (e.g. Anthropic, which supports text file parts) reused with xAI.","solutions":["Convert the text file content to a TextPart (inline the text into the prompt) before sending.","If sending a document, use a provider that supports text file parts, or extract text yourself.","Filter out text file parts with a warning before the call."],"exampleFix":"// before\nmessages: [{ role: 'user', content: [{ type: 'file', data: txtBuffer, mediaType: 'text/plain' }] }]\n// after\nmessages: [{ role: 'user', content: [{ type: 'text', text: txtBuffer.toString('utf-8') }] }]","handlingStrategy":"validation","validationCode":"function assertNoTextFileParts(messages: ModelMessage[]) {\n  for (const m of messages) {\n    for (const p of Array.isArray(m.content) ? m.content : []) {\n      if (p.type === 'file' && p.mediaType.startsWith('text/')) {\n        throw new Error(`Convert text file part (${p.mediaType}) to a text part before sending to xAI`);\n      }\n    }\n  }\n}","typeGuard":"const isImageFilePart = (p: unknown): p is FilePart & { mediaType: `image/${string}` } =>\n  typeof p === 'object' && p !== null && (p as any).type === 'file' &&\n  String((p as any).mediaType).startsWith('image/');","tryCatchPattern":"try {\n  await generateText({ model: xai('grok-4'), messages });\n} catch (e) {\n  if (UnsupportedFunctionalityError.isInstance(e) && e.functionality === 'text file parts') {\n    messages = messages.map(convertTextFilePartsToText);\n    return generateText({ model: xai('grok-4'), messages });\n  }\n  throw e;\n}","preventionTips":["Map uploaded text/.txt/.csv files to TextParts before calling xAI models.","Write a provider-agnostic preprocessing step for message content per provider.","Add a unit test asserting message content passed to xai contains no text file parts."],"tags":["xai","file-parts","unsupported"],"backgroundTag":"unsupported-functionality","analyzedSha":"69428b1f8b037e4d118fb4853428d5c4e620493c","analyzedAt":"2026-08-30T12:32:21.016Z","schemaVersion":2},"datasetVersion":"2026-08-30T13:17:10.514Z"}