{"record":{"id":"d4bf2b2a295ce234","repo":"wavetermdev/waveterm","slug":"dropping-file-with-unsupported-media-type-s-mu","errorCode":null,"errorMessage":"dropping file with unsupported media type '%s' (must be uploaded to Files API and sent as file_id)","messagePattern":"dropping file with unsupported media type '(.+?)' \\(must be uploaded to Files API and sent as file_id\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/aiusechat/anthropic/anthropic-convertmessage.go","lineNumber":454,"sourceCode":"\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"failed to decode base64 data: %w\", err)\n\t\t\t}\n\t\t\treturn &anthropicMessageContentBlock{\n\t\t\t\tType: \"document\",\n\t\t\t\tSource: &anthropicSource{\n\t\t\t\t\tType:      \"text\",\n\t\t\t\t\tData:      string(textData),\n\t\t\t\t\tMediaType: \"text/plain\",\n\t\t\t\t},\n\t\t\t}, nil\n\t\t} else {\n\t\t\t// HTTP/HTTPS URL → not supported inline, would need to fetch\n\t\t\treturn nil, fmt.Errorf(\"dropping text/plain file with URL (must be fetched and converted to base64 or uploaded to Files API)\")\n\t\t}\n\n\tdefault:\n\t\t// Other media types → not supported inline, must upload and use file_id\n\t\treturn nil, fmt.Errorf(\"dropping file with unsupported media type '%s' (must be uploaded to Files API and sent as file_id)\", p.MediaType)\n\t}\n\n}\n\n// convertAIMessageToAnthropicChatMessage converts an AIMessage to anthropicChatMessage\n// These messages are ALWAYS role \"user\"\nfunc ConvertAIMessageToAnthropicChatMessage(aiMsg uctypes.AIMessage) (*anthropicChatMessage, error) {\n\tif err := aiMsg.Validate(); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid AIMessage: %w\", err)\n\t}\n\n\tvar contentBlocks []anthropicMessageContentBlock\n\n\tfor i, part := range aiMsg.Parts {\n\t\tswitch part.Type {\n\t\tcase uctypes.AIMessagePartTypeText:\n\t\t\tif part.Text == \"\" {\n\t\t\t\treturn nil, fmt.Errorf(\"part %d: text type requires non-empty text field\", i)","sourceCodeStart":436,"sourceCodeEnd":472,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/pkg/aiusechat/anthropic/anthropic-convertmessage.go#L436-L472","documentation":"The Anthropic converter only supports image/*, application/pdf, and text/plain media types for inline conversion. Any other media type (audio, video, zip, office docs, etc.) cannot be sent inline and must be uploaded to Anthropic's Files API and referenced by file_id, so the library rejects the part with this error rather than silently producing a bad block.","triggerScenarios":"Sending a UIMessagePart or AIMessagePart with Type \"file\" whose MediaType is e.g. audio/mpeg, video/mp4, application/zip, application/vnd.openxmlformats-officedocument.wordprocessingml.document — anything not image/*, application/pdf, or text/plain.","commonSituations":"Attaching audio/video recordings from a chat UI; sending Excel/Word/CSV(odd mime) attachments; forwarding arbitrary user uploads straight to the model without filtering.","solutions":["Upload the file to the Anthropic Files API and reference it via file_id in your request","Restrict accepted attachments to images, PDFs, and text before they reach the converter","Transcode non-image media into a supported representation (e.g. transcribe audio to text, convert docs to PDF/text)"],"exampleFix":"// before\npart := uctypes.UIMessagePart{Type: \"file\", MediaType: \"audio/mpeg\", URL: dataURL}\n// after\n// transcribe or convert first\npart := uctypes.UIMessagePart{Type: \"file\", MediaType: \"text/plain\", URL: \"data:text/plain;base64,\" + base64.StdEncoding.EncodeToString(transcript)}","handlingStrategy":"validation","validationCode":"func inlineSupported(mime string) bool {\n    return strings.HasPrefix(mime, \"image/\") || mime == \"application/pdf\" || mime == \"text/plain\"\n}\nif !inlineSupported(p.MediaType) { /* upload to Files API or reject */ }","typeGuard":"func isInlineableMedia(mime string) bool {\n    return strings.HasPrefix(mime, \"image/\") || mime == \"application/pdf\" || mime == \"text/plain\"\n}","tryCatchPattern":"if err := convert(msg); err != nil {\n    if strings.Contains(err.Error(), \"unsupported media type\") {\n        fileID, uerr := uploadToAnthropicFiles(part)\n        if uerr == nil { return convert(withFileID(msg, fileID)) }\n    }\n    return err\n}","preventionTips":["Whitelist accepted attachment mime types at ingestion (image/*, application/pdf, text/plain)","Implement a Files API upload path for everything else","Convert/transcode audio, video, and office docs into supported formats before sending"],"tags":["go","anthropic","unsupported-media-type","files-api"],"backgroundTag":"unsupported-media-type","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}