{"record":{"id":"71b48ed702714c44","repo":"mastra-ai/mastra","slug":"unsupported-url-protocol-url-protocol","errorCode":null,"errorMessage":"Unsupported URL protocol: ${url.protocol}","messagePattern":"Unsupported URL protocol: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/core/src/agent/message-list/prompt/attachments-to-parts.ts","lineNumber":95,"sourceCode":"            mimeType: attachment.contentType,\n          });\n        } else {\n          if (!attachment.contentType) {\n            throw new Error('If the attachment is not an image or text, it must specify a content type');\n          }\n\n          parts.push({\n            type: 'file',\n            data: urlString,\n            mimeType: attachment.contentType,\n          });\n        }\n\n        break;\n      }\n\n      default: {\n        throw new Error(`Unsupported URL protocol: ${url.protocol}`);\n      }\n    }\n  }\n\n  return parts;\n}\n","sourceCodeStart":77,"sourceCodeEnd":102,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/agent/message-list/prompt/attachments-to-parts.ts#L77-L102","documentation":"attachmentsToParts only supports URL schemes the AI providers accept: http:, https:, and cloud-storage schemes data/fetch families plus gs: and s3:. Any other protocol falls into the default branch and throws 'Unsupported URL protocol: <protocol>'.","triggerScenarios":"Adding an attachment whose URL uses an unsupported scheme — e.g. file:///home/user/cat.png, ftp://..., blob:https://..., or chrome:// — when converting user content to AI SDK parts.","commonSituations":"Browser apps accidentally passing blob: URLs created by URL.createObjectURL; Node code passing local filesystem paths as file:// URLs; internal CDNs on custom schemes.","solutions":["Convert blob:/file: references to http(s) URLs or inline data: URLs (base64) before adding the message.","For local files, read bytes yourself and pass them as binary/data content instead of a file:// URL.","Upload the asset to accessible storage (S3/GCS/HTTP) and reference it with a supported scheme.","Allowlist supported schemes (http:, https:, data:, gs:, s3:) in your app's attachment validation."],"exampleFix":"// before\n{ url: 'file:///tmp/cat.png' }\n// after\n{ url: 'data:image/png;base64,' + fs.readFileSync('/tmp/cat.png').toString('base64') }","handlingStrategy":"validation","validationCode":"const SUPPORTED = new Set(['http:', 'https:', 'data:', 'gs:', 's3:']);\nfunction assertSupportedProtocol(u: string) {\n  const p = new URL(u).protocol;\n  if (!SUPPORTED.has(p)) throw new Error(`Protocol ${p} not supported; use http/https/data/gs/s3`);\n}","typeGuard":"function hasSupportedProtocol(u: string): boolean {\n  try { return ['http:', 'https:', 'data:', 'gs:', 's3:'].includes(new URL(u).protocol); }\n  catch { return false; }\n}","tryCatchPattern":"try {\n  messageList.add(toUserContent(attachment));\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('Unsupported URL protocol:')) {\n    const inlined = await inlineAsDataUrl(attachment.url); // read blob/file locally\n    messageList.add(toUserContent({ ...attachment, url: inlined }));\n  } else throw e;\n}","preventionTips":["Convert blob: URLs to data: URLs before sending to the server (createObjectURL outputs are not fetchable server-side).","Upload local files to accessible storage and reference via https://.","Allowlist supported schemes in your attachment validation layer."],"tags":["url","attachment","protocol","validation"],"backgroundTag":"unsupported-url-protocol","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}