wavetermdev/waveterm · error
dropping text/plain file with URL (must be fetched and…
Error message
dropping text/plain file with URL (must be fetched and converted to base64 or uploaded to Files API)
What it means
text/plain file parts are only supported when embedded inline as a data: URL (decoded to an Anthropic plain-text document source). The Anthropic API has no URL-based text document form this converter can use, so a text/plain part carrying an http(s) URL is rejected with this error telling you to fetch the content yourself and inline it, or upload via the Files API.
Solutions
- Fetch the URL server-side, then send the content as a data:text/plain;base64,... data URL
- Upload the file to the Anthropic Files API and reference it by file_id
- Inline the text directly as a text part (uctypes text part) instead of a file part
Example fix
// before
part := uctypes.UIMessagePart{Type: "file", MediaType: "text/plain", URL: "https://cdn.example.com/notes.txt"}
// after
body, _ := http.Get(part.URL) // fetch and inline
b64 := base64.StdEncoding.EncodeToString(body)
part := uctypes.UIMessagePart{Type: "file", MediaType: "text/plain", URL: "data:text/plain;base64," + b64} Defensive patterns
Strategy: fallback
Validate before calling
if p.MediaType == "text/plain" && !strings.HasPrefix(p.URL, "data:") {
// fetch and inline, or convert to a text part, before calling the API
} Type guard
func isSupportedTextFilePart(p uctypes.UIMessagePart) bool {
return p.MediaType != "text/plain" || strings.HasPrefix(p.URL, "data:")
} Try / catch
if err := convert(msg); err != nil {
if strings.Contains(err.Error(), "dropping text/plain file with URL") {
body, ferr := http.Get(p.URL)
if ferr == nil { return convert(withDataURL(msg, body)) }
}
return err
} Prevention
- Pre-fetch any http(s) text file server-side and inline it as a data URL
- Prefer a plain text part over a text/plain file part for hosted text content
- Keep a small pre-flight validator mirroring the converter's media-type/URL rules
When it happens
Trigger: Creating a UIMessagePart{Type:"file", MediaType:"text/plain", URL:"https://..."} and sending it through ConvertUIMessageToAnthropicChatMessage — the error fires in the else branch at anthropic-convertmessage.go:447-450.
Common situations: Pointing at a raw .txt/.md/.csv file hosted on S3/CDN; passing a chat file attachment that the client stored as an http URL; migrating from OpenAI-style converters where URL text files were accepted.
Related errors
- APIType must be ' ', got
- chat not found
- convertFileAIMessagePart expects 'file' type, got
- convertFileUIMessagePart expects 'file' type, got
- dropping file with unsupported media type
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/7a871a769622b270.
Report an issue: GitHub.
Appendix: source
Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:449
if len(parts) != 2 {
return nil, errors.New("invalid data URL format")
}
// Decode base64 data
textData, err := base64.StdEncoding.DecodeString(parts[1])
if err != nil {
return nil, fmt.Errorf("failed to decode base64 data: %w", err)
}
return &anthropicMessageContentBlock{
Type: "document",
Source: &anthropicSource{
Type: "text",
Data: string(textData),
MediaType: "text/plain",
},
}, nil
} else {
// HTTP/HTTPS URL → not supported inline, would need to fetch
return nil, fmt.Errorf("dropping text/plain file with URL (must be fetched and converted to base64 or uploaded to Files API)")
}
default:
// Other media types → not supported inline, must upload and use file_id
return nil, fmt.Errorf("dropping file with unsupported media type '%s' (must be uploaded to Files API and sent as file_id)", p.MediaType)
}
}
// convertAIMessageToAnthropicChatMessage converts an AIMessage to anthropicChatMessage
// These messages are ALWAYS role "user"
func ConvertAIMessageToAnthropicChatMessage(aiMsg uctypes.AIMessage) (*anthropicChatMessage, error) {
if err := aiMsg.Validate(); err != nil {
return nil, fmt.Errorf("invalid AIMessage: %w", err)
}
var contentBlocks []anthropicMessageContentBlock
View on GitHub (pinned to a4447c1563)