wavetermdev/waveterm · error
unsupported URL protocol in file part: %s
Error message
unsupported URL protocol in file part: %s
What it means
The Anthropic converter only accepts file-part URLs with a data:, http://, or https:// scheme. Any other protocol (ftp://, file://, blob:, ws:, or a bare path like /tmp/x.png) is rejected before any block is built, because the library will not fetch arbitrary schemes or guess a source type. For AIMessageParts (unlike UIMessageParts) this check only applies when a URL is present at all.
Source
Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:367
}
// convertFileUIMessagePart converts a file part to Anthropic image or document block format
func convertFileUIMessagePart(p uctypes.UIMessagePart) (*anthropicMessageContentBlock, error) {
if p.Type != "file" {
return nil, fmt.Errorf("convertFileUIMessagePart expects 'file' type, got '%s'", p.Type)
}
if p.URL == "" {
return nil, errors.New("file part missing url")
}
if p.MediaType == "" {
return nil, errors.New("file part missing mediaType")
}
// Validate URL protocol - only allow data:, http:, https:
if !strings.HasPrefix(p.URL, "data:") &&
!strings.HasPrefix(p.URL, "http://") &&
!strings.HasPrefix(p.URL, "https://") {
return nil, fmt.Errorf("unsupported URL protocol in file part: %s", p.URL)
}
// Branch on mediaType first to determine block type and constraints
switch {
case strings.HasPrefix(p.MediaType, "image/"):
// image/* (jpeg, png, gif, webp) → Anthropic image block
if strings.HasPrefix(p.URL, "data:") {
// Data URL → base64 source
parts := strings.SplitN(p.URL, ",", 2)
if len(parts) != 2 {
return nil, errors.New("invalid data URL format")
}
return &anthropicMessageContentBlock{
Type: "image",
Source: &anthropicSource{
Type: "base64",
Data: parts[1],
MediaType: p.MediaType,View on GitHub (pinned to a4447c1563)
Solutions
- Convert the file content to a data: URL (base64) before building the part
- Serve the file over public http(s) and use that URL instead
- Upload to the Anthropic Files API and reference by file_id if supported by your flow
- Strip or fix blob:/file:/custom-scheme URLs when ingesting parts from the frontend
Example fix
// before
part := uctypes.UIMessagePart{Type: "file", URL: "file:///tmp/report.pdf", MediaType: "application/pdf"}
// after
data, _ := os.ReadFile("/tmp/report.pdf")
part := uctypes.UIMessagePart{Type: "file", URL: "data:application/pdf;base64," + base64.StdEncoding.EncodeToString(data), MediaType: "application/pdf"} Defensive patterns
Strategy: validation
Validate before calling
func validURLScheme(u string) bool {
return strings.HasPrefix(u, "data:") || strings.HasPrefix(u, "http://") || strings.HasPrefix(u, "https://")
}
if part.URL != "" && !validURLScheme(part.URL) { return fmt.Errorf("unsupported scheme: %s", part.URL) } Type guard
func isFetchableOrDataURL(u string) bool {
return strings.HasPrefix(u, "data:") || strings.HasPrefix(u, "http://") || strings.HasPrefix(u, "https://")
} Try / catch
if err := convertAndSend(part); err != nil {
var protoErr = "unsupported URL protocol"
if strings.Contains(err.Error(), protoErr) {
// fall back: fetch bytes and resend as data: URL
return resendAsDataURL(part)
}
return err
} Prevention
- Convert local/blob/custom-scheme URLs to base64 data URLs before building parts
- Run url.Parse and check the scheme whitelist at part-construction time
- Never pass browser blob: URLs to server-side converters
When it happens
Trigger: Setting p.URL to an unsupported scheme such as file:///home/user/doc.pdf, ftp://..., blob:..., or a bare local path and then sending the message through ConvertUIMessageToAnthropicChatMessage / convertFileUIMessagePart.
Common situations: Server-side code reusing browser blob: URLs that are meaningless outside the client; passing local filesystem paths as URLs; generating presigned or internal scheme URLs (s3://, gs://) that Anthropic cannot consume.
Related errors
- convertFileUIMessagePart expects 'file' type, got '%s'
- failed to decode base64 data: %w
- dropping text/plain file with URL (must be fetched and conve
- dropping file with unsupported media type '%s' (must be uplo
- invalid AIMessage: %w
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/6f3ca9da6ee92e99.
Report an issue: GitHub.