wavetermdev/waveterm · error

PDF file part missing data

Error message

PDF file part missing data

What it means

A PDF file part has neither Data nor URL — it's completely empty. The converter requires base64-encodable raw bytes for PDFs, so it rejects the part. This means the attachment failed to load or was never populated upstream.

Source

Thrown at pkg/aiusechat/openai/openai-convertmessage.go:353

		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, err
		}
		formattedText := aiutil.FormatAttachedTextFile(part.FileName, textData)

View on GitHub (pinned to a4447c1563)

Solutions

  1. Populate part.Data with the PDF bytes read from disk/storage before sending
  2. Add an os.ReadFile / storage-fetch error check so empty reads are caught before building the message
  3. Validate that len(part.Data) > 0 for every PDF part in a pre-send validation pass

Example fix

// before
part := uctypes.AIMessagePart{Type: "file", MimeType: "application/pdf", FileName: path} // no data
// after
data, err := os.ReadFile(path)
if err != nil { return err }
part := uctypes.AIMessagePart{Type: "file", MimeType: "application/pdf", FileName: path, Data: data}
Defensive patterns

Strategy: validation

Validate before calling

func ensurePDFData(p uctypes.AIMessagePart) error {
    if p.MimeType == "application/pdf" && len(p.Data) == 0 {
        return errors.New("PDF part has no data")
    }
    return nil
}

Type guard

func hasPDFData(p uctypes.AIMessagePart) bool {
    return p.MimeType == "application/pdf" && len(p.Data) > 0
}

Prevention

When it happens

Trigger: Constructing an AIMessagePart with MimeType "application/pdf" but forgetting to load file bytes into Data; a prior download/read step failed silently leaving Data nil; serializing/deserializing messages lost the binary payload.

Common situations: File read errors swallowed upstream; database/blob-store lookups returning empty for the attachment; passing only FileName metadata without content.

Related errors


AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01). Data as JSON: /api/errors/f75cc88914ddcb79. Report an issue: GitHub.