mastra-ai/mastra · error
Invalid URL: ${attachment.url}
Error message
Invalid URL: ${attachment.url} What it means
attachmentsToParts parses each attachment URL with new URL() before mapping it to an AI-SDK content part. If the URL string cannot be parsed (malformed scheme, missing protocol, spaces, etc.), a plain Error 'Invalid URL: <url>' is thrown, because the rest of the function branches on url.protocol and cannot proceed.
Source
Thrown at packages/core/src/agent/message-list/prompt/attachments-to-parts.ts:41
parts.push({
type: 'file',
data: attachment.url,
mimeType: attachment.contentType || 'application/octet-stream',
});
continue;
}
// If it's raw data (base64), convert it to a data URI
let urlString = attachment.url;
if (categorized.type === 'raw') {
urlString = createDataUri(attachment.url, attachment.contentType || 'application/octet-stream');
}
let url;
try {
url = new URL(urlString);
} catch {
throw new Error(`Invalid URL: ${attachment.url}`);
}
switch (url.protocol) {
case 'http:':
case 'https:':
// Cloud storage protocols supported by AI providers (e.g., Vertex AI for gs://, Bedrock for s3://)
case 'gs:':
case 's3:': {
if (attachment.contentType?.startsWith('image/')) {
parts.push({ type: 'image', image: url.toString(), mimeType: attachment.contentType });
} else {
if (!attachment.contentType) {
throw new Error('If the attachment is not an image, it must specify a content type');
}
parts.push({
type: 'file',
data: url.toString(),View on GitHub (pinned to 75dd419e61)
Solutions
- Prepend a scheme to the string, e.g. 'https://' + value, before creating the attachment.
- Encode the URL properly with encodeURI/encodeURIComponent for spaces and special characters.
- For local files, read them yourself and pass data: URLs (base64 data content) or binary parts instead of file paths.
- Validate attachment URLs with new URL() at the UI/validation layer before sending to the agent.
Example fix
// before
{ url: 'example.com/cat.png' }
// after
{ url: 'https://example.com/cat.png' } Defensive patterns
Strategy: validation
Validate before calling
function assertHttpUrl(u: string) {
const url = new URL(u); // throws like the library does
if (!['http:', 'https:', 'data:', 'gs:', 's3:'].includes(url.protocol)) {
throw new Error(`Unsupported protocol ${url.protocol}`);
}
} Type guard
function isParsableUrl(u: unknown): u is string {
if (typeof u !== 'string') return false;
try { new URL(u); return true; } catch { return false; }
} Try / catch
try {
messageList.add({ role: 'user', content: [{ type: 'image', image: attachment.url }] });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid URL:')) {
notifyUser(`Attachment URL "${attachment.url}" is malformed; include a scheme like https://`);
} else throw e;
} Prevention
- Validate attachment URLs with new URL() at the UI/API boundary before submitting.
- Require a scheme in input fields; auto-prefix https:// for bare domains.
- Encode user-supplied URLs with encodeURI before attaching.
When it happens
Trigger: Adding a user message via MessageList user content conversion with an attachment whose url field is not a parseable URL string — e.g. 'example.com/img.png' (no scheme), 'htp://...', or a URL containing unencoded spaces/special characters.
Common situations: Users pasting bare domains without http(s):// into chat UIs; frontend code passing file paths like '/uploads/x.png' as attachment URLs; environment misconfig producing empty or partial base URLs.
Related errors
- Unsupported URL protocol: ${url.protocol}
- Invalid route path: "${path}". Path cannot contain '..', '?'
- Factory linked work item URL is invalid.
- If the attachment is not an image, it must specify a content
- If the attachment is not an image or text, it must specify a
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/25f62a56163a1ed3.
Report an issue: GitHub.