wavetermdev/waveterm · error

file part missing url

Error message

file part missing url

What it means

convertFileUIMessagePart converts a UI message 'file' part into an Anthropic image/document block. A file part with no URL has no source data whatsoever, so conversion is impossible and the function returns 'file part missing url'. Anthropic blocks need either a base64 payload or a fetchable URL.

Source

Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:357

	for _, p := range parts {
		partBlocks, err := convertPartToAnthropicBlocks(p, role, len(blocks))
		if err != nil {
			log.Printf("anthropic: %v", err)
			continue
		}
		blocks = append(blocks, partBlocks...)
	}

	return blocks, nil
}

// 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

View on GitHub (pinned to a4447c1563)

Solutions

  1. Populate p.URL with a data:, http://, or https:// URL before sending the message.
  2. Filter out file parts with empty URLs prior to calling the conversion/chat step.
  3. Fix the producer so the part is only emitted after the upload/data-url encoding completes.

Example fix

// before
part := uctypes.UIMessagePart{Type: "file", MediaType: "image/png"}

// after
dataURL := "data:image/png;base64," + base64.StdEncoding.EncodeToString(pngBytes)
part := uctypes.UIMessagePart{Type: "file", MediaType: "image/png", URL: dataURL}
Defensive patterns

Strategy: validation

Validate before calling

for _, p := range msg.Parts {
    if p.Type == "file" && p.URL == "" {
        return fmt.Errorf("dropping/fixing file part with empty url (mediaType=%s)", p.MediaType)
    }
}

Type guard

func hasValidFileURL(p uctypes.UIMessagePart) bool {
    return p.Type == "file" && p.URL != ""
}

Try / catch

blocks, err := convertPartToAnthropicBlocks(part)
if err != nil && strings.Contains(err.Error(), "file part missing url") {
    return fmt.Errorf("attachment has no source data; re-upload the file: %w", err)
}

Prevention

When it happens

Trigger: Sending a chat message whose parts include {Type: "file"} with URL == "" — e.g. an attachment whose upload never completed, or a client that only set MediaType/FileName.

Common situations: Frontend dropping a file before upload finished and still emitting the part; drag-and-drop handling that creates the part before reading the file; copying message-construction code and omitting the URL field.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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