wavetermdev/waveterm · error
file part missing mediaType
Error message
file part missing mediaType
What it means
After the URL check, convertFileUIMessagePart requires p.MediaType to decide the Anthropic block shape: image/* becomes an image block, application/pdf and text/plain become document blocks. Without MediaType the converter cannot choose a block type, so it errors with 'file part missing mediaType'.
Source
Thrown at pkg/aiusechat/anthropic/anthropic-convertmessage.go:360
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
parts := strings.SplitN(p.URL, ",", 2)
if len(parts) != 2 {
return nil, errors.New("invalid data URL format")View on GitHub (pinned to a4447c1563)
Solutions
- Set p.MediaType (e.g. "image/png", "application/pdf", "text/plain") on the file part.
- Infer the MIME type from the file extension or response Content-Type before sending.
- Drop or convert unsupported media-type-less parts before the chat call.
Example fix
// before
part := uctypes.UIMessagePart{Type: "file", URL: dataURL}
// after
part := uctypes.UIMessagePart{Type: "file", URL: dataURL, MediaType: "image/png"} Defensive patterns
Strategy: validation
Validate before calling
if p.Type == "file" && p.MediaType == "" {
return fmt.Errorf("file part %s requires mediaType", p.URL)
} Type guard
func hasMediaType(p uctypes.UIMessagePart) bool {
return p.Type != "file" || p.MediaType != ""
} Try / catch
blocks, err := convertPartToAnthropicBlocks(part)
if err != nil && strings.Contains(err.Error(), "file part missing mediaType") {
return fmt.Errorf("set MediaType from file extension or Content-Type: %w", err)
} Prevention
- Record the MIME type at file-selection time, not at send time.
- Use mime.TypeByExtension(filepath.Ext(name)) as a fallback when unknown.
- Reject media-type-less attachments in message validation.
When it happens
Trigger: A file part with a non-empty URL but MediaType == "" passed into convertPartToAnthropicBlocks, e.g. a URL-only attachment where the client never recorded the MIME type.
Common situations: Constructing parts from raw URLs fetched at runtime without sniffing the content type; older client payloads predating the mediaType field; hand-built message fixtures in tests.
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
- file part missing url
- invalid data URL format
- toolResults cannot be empty
- invalid AIMessage: %w
- convertFileAIMessagePart expects 'file' type, got '%s'
AI-assisted analysis of wavetermdev/waveterm@a4447c1563 (2026-09-01).
Data as JSON: /api/errors/9e8c4ba68a95c7ff.
Report an issue: GitHub.