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.

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.

Appendix: 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)