wavetermdev/waveterm · error
dropping PDF with URL (must be fetched and converted to base
Error message
dropping PDF with URL (must be fetched and converted to base64 data)
What it means
OpenAI's API only accepts PDFs as base64-encoded data, never as URLs. The converter found a PDF part with a URL but no inline Data, and returns this error instead of silently sending an unsupported URL-based PDF.
Source
Thrown at pkg/aiusechat/openai/openai-convertmessage.go:351
switch {
case strings.HasPrefix(part.MimeType, "image/"):
imageUrl, err := aiutil.ExtractImageUrl(part.Data, part.URL, part.MimeType)
if err != nil {
return nil, err
}
return &OpenAIMessageContent{
Type: "input_image",
ImageUrl: imageUrl,
Filename: part.FileName,
PreviewUrl: part.PreviewUrl,
}, nil
case part.MimeType == "application/pdf":
// Handle PDFs - OpenAI only supports base64 data for PDFs, not URLs
if len(part.Data) == 0 {
if part.URL != "" {
return nil, fmt.Errorf("dropping PDF with URL (must be fetched and converted to base64 data)")
}
return nil, fmt.Errorf("PDF file part missing data")
}
// Convert raw data to base64
base64Data := base64.StdEncoding.EncodeToString(part.Data)
return &OpenAIMessageContent{
Type: "input_file",
Filename: part.FileName, // Optional filename
FileData: base64Data,
PreviewUrl: part.PreviewUrl,
}, nil
case part.MimeType == "text/plain":
textData, err := aiutil.ExtractTextData(part.Data, part.URL)
if err != nil {
return nil, errView on GitHub (pinned to a4447c1563)
Solutions
- Fetch the PDF yourself, put the raw bytes into part.Data, and clear part.URL
- Base64-encode is handled by the converter — only raw bytes are needed in Data
- Pre-download attachments in your ingestion pipeline before constructing message parts
Example fix
// before
part := uctypes.AIMessagePart{Type: "file", MimeType: "application/pdf", URL: "https://cdn.example.com/doc.pdf"}
// after
data, _ := http.Get(part.URL) // fetch first
body, _ := io.ReadAll(data.Body)
part := uctypes.AIMessagePart{Type: "file", MimeType: "application/pdf", Data: body} Defensive patterns
Strategy: validation
Validate before calling
func validatePDFPart(p uctypes.AIMessagePart) error {
if p.MimeType != "application/pdf" { return nil }
if len(p.Data) == 0 && p.URL != "" {
return errors.New("PDF has URL only; fetch bytes into Data first")
}
return nil
} Type guard
func hasInlinePDFData(p uctypes.AIMessagePart) bool {
return p.MimeType == "application/pdf" && len(p.Data) > 0
} Prevention
- Always download PDFs to bytes before attaching; never pass URLs
- Normalize parts from other providers (Claude-style URL PDFs) at ingestion
- Pre-send validation pass over all file parts
When it happens
Trigger: Building a file part with MimeType "application/pdf", part.URL set to a web/CDN link, and part.Data empty; passing through attachment metadata from another provider (e.g. Anthropic/Claude-style URL PDFs) directly to the OpenAI backend.
Common situations: Migrating chat pipelines from Claude (which accepts PDF URLs) to OpenAI; storing files behind signed URLs and referencing them by link; frontend sending upload URLs instead of downloaded bytes.
Related errors
- PDF file part missing data
- convertFileAIMessagePart expects 'file' type, got '%s'
- file part missing mimetype
- directory listing part missing data
- dropping file with unsupported mimetype '%s' (OpenAI support
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/b17d252a606c6966.
Report an issue: GitHub.