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 is not supported.

What it means

Assistant ('reasoning-file') parts whose data is a URL cannot be converted for Google: the Gemini/Vertex content format requires reasoning/thinking file attachments as inline bytes, not remote URLs. The converter throws UnsupportedFunctionalityError when it hits a reasoning-file part with `type: 'url'`.

Source

Thrown at packages/google/src/convert-to-google-messages.ts:383

                        text: part.text,
                        thoughtSignature,
                      };
                }

                case 'reasoning': {
                  return part.text.length === 0
                    ? undefined
                    : {
                        text: part.text,
                        thought: true,
                        thoughtSignature,
                      };
                }

                case 'reasoning-file': {
                  switch (part.data.type) {
                    case 'url': {
                      throw new UnsupportedFunctionalityError({
                        functionality:
                          'File data URLs in assistant messages are not supported',
                      });
                    }
                    case 'data': {
                      return {
                        inlineData: {
                          mimeType: part.mediaType,
                          data: convertToBase64(part.data.data),
                        },
                        thought: true,
                        thoughtSignature,
                      };
                    }
                  }
                  break;
                }

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Download the file and resend it as inline data: `data: { type: 'data', mediaType, data: base64 }`.
  2. Strip reasoning-file parts from the history when switching to Google models.
  3. Store base64/raw bytes instead of URLs in your message persistence layer.

Example fix

// before
{ type: 'reasoning-file', data: { type: 'url', url: 'https://.../thinking.json' } }
// after
{ type: 'reasoning-file', data: { type: 'data', mediaType: 'application/json', data: base64Content } }
Defensive patterns

Strategy: try-catch

Validate before calling

function reasoningFilesHaveNoUrls(messages) {
  return messages.flatMap(m => Array.isArray(m.content) ? m.content : [])
    .every(p => p.type !== 'reasoning-file' || p.data?.type !== 'url');
}

Type guard

function isDataReasoningFile(part) {
  return part?.type === 'reasoning-file' && part?.data?.type === 'data';
}

Try / catch

try {
  await streamText({ model: googleModel, messages });
} catch (e) {
  if (e?.message?.includes('File data URLs in assistant messages are not supported')) {
    const sanitized = messages.map(m => m.role === 'assistant'
      ? { ...m, content: m.content.filter(p => p.type !== 'reasoning-file') } : m);
    return streamText({ model: googleModel, messages: sanitized });
  } throw e;
}

Prevention

When it happens

Trigger: A message array containing an assistant message with a `reasoning-file` part whose `data.type` is 'url' (e.g. from a previous provider response that returned a hosted file URL), sent to a Google model.

Common situations: Carrying multi-provider conversation history where an earlier provider returned hosted thinking-file URLs; persisting assistant outputs as URLs in a database and replaying them against Google.

Related errors


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