{"record":{"id":"e28e5059d4fa8b4b","repo":"siyuan-note/siyuan","slug":"unsupported-image-type-s","errorCode":null,"errorMessage":"unsupported image type: %s","messagePattern":"unsupported image type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":775,"sourceCode":"\treturn\n}\n\n// PrepareModelImage 校验并按需缩放图片，尽量保留多模态模型支持的原始格式和图片质量。\nfunc PrepareModelImage(data []byte, maxBytes, maxPixels, maxEdge int) (PreparedImage, error) {\n\tif len(data) == 0 {\n\t\treturn PreparedImage{}, errors.New(\"image data is empty\")\n\t}\n\tif maxBytes > 0 && len(data) > maxBytes {\n\t\treturn PreparedImage{}, fmt.Errorf(\"image exceeds size limit: %d bytes\", maxBytes)\n\t}\n\tmimeType := mimetype.Detect(data).String()\n\tif strings.Contains(mimeType, \"svg\") || bytes.Contains(bytes.ToLower(data[:min(len(data), 512)]), []byte(\"<svg\")) {\n\t\treturn PreparedImage{}, errors.New(\"SVG images are not accepted by multimodal models\")\n\t}\n\tswitch mimeType {\n\tcase \"image/gif\", \"image/jpeg\", \"image/png\", \"image/webp\":\n\tdefault:\n\t\treturn PreparedImage{}, fmt.Errorf(\"unsupported image type: %s\", mimeType)\n\t}\n\tconfig, _, err := image.DecodeConfig(bytes.NewReader(data))\n\tif err != nil {\n\t\treturn PreparedImage{}, errors.New(\"unsupported or invalid image: \" + err.Error())\n\t}\n\tif config.Width < 1 || config.Height < 1 || maxPixels > 0 && int64(config.Width)*int64(config.Height) > int64(maxPixels) {\n\t\treturn PreparedImage{}, fmt.Errorf(\"image exceeds pixel limit: %d\", maxPixels)\n\t}\n\n\tdecoded, err := imaging.Decode(bytes.NewReader(data), imaging.AutoOrientation(true))\n\tif err != nil {\n\t\treturn PreparedImage{}, errors.New(\"decode image failed: \" + err.Error())\n\t}\n\tbounds := decoded.Bounds()\n\tneedsResize := maxEdge > 0 && (bounds.Dx() > maxEdge || bounds.Dy() > maxEdge)\n\tif !needsResize && bounds.Dx() == config.Width && bounds.Dy() == config.Height && mimeType != \"image/gif\" {\n\t\treturn PreparedImage{\n\t\t\tData:       data,","sourceCodeStart":757,"sourceCodeEnd":793,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/9f775e8a12daef8255556097396f9b2739078892/kernel/util/openai.go#L757-L793","documentation":"PrepareModelImage accepts only image/gif, image/jpeg, image/png, and image/webp as detected MIME types; any other detected type (BMP, TIFF, HEIC, AVIF, PDF, text, etc.) yields this error naming the detected MIME type. These four formats are what mainstream multimodal APIs accept, so everything else is rejected before decoding.","triggerScenarios":"Calling PrepareModelImage on data whose mimetype.Detect result is not one of the four supported types — e.g. attaching a .bmp screenshot, an iPhone .heic photo, a TIFF scan, or accidentally a non-image file.","commonSituations":"iOS/macOS HEIC photos copied straight into SiYuan; Windows BMP screenshots from legacy tools; TIFF scans from scanners; an asset file that is actually a document or text file misnamed with an image extension.","solutions":["Convert the image to PNG, JPEG, or WebP before attaching (any image converter or 'open in editor, save as PNG')","For HEIC photos, convert to JPEG during import or via the OS image pipeline","Verify the file is actually an image — the MIME type in the error reveals the true content type","If inserting via automation, normalize all assets to PNG/JPEG as a preprocessing step"],"exampleFix":"// before\nprepared, err := PrepareModelImage(heicBytes, maxBytes, maxPixels, maxEdge) // \"unsupported image type: image/heic\"\n// after\njpegBytes := convert(heicBytes, \"image/jpeg\") // transcode HEIC to JPEG first\nprepared, err := PrepareModelImage(jpegBytes, maxBytes, maxPixels, maxEdge)","handlingStrategy":"validation","validationCode":"mt := mimetype.Detect(data).String()\nif !isRasterImage(mt) { data = transcodeToJPEG(data) }","typeGuard":"func isRasterImage(mt string) bool {\n    switch mt {\n    case \"image/gif\", \"image/jpeg\", \"image/png\", \"image/webp\":\n        return true\n    }\n    return false\n}","tryCatchPattern":"prepared, err := PrepareModelImage(data, maxBytes, maxPixels, maxEdge)\nif err != nil && strings.Contains(err.Error(), \"unsupported image type\") {\n    prepared, err = PrepareModelImage(transcodeToJPEG(data), maxBytes, maxPixels, maxEdge)\n}","preventionTips":["Convert HEIC/BMP/TIFF assets to JPEG/PNG at import time","Trust the MIME type in the error message over the file's extension","Normalize all programmatically inserted images to PNG or JPEG"],"tags":["image","unsupported-format","multimodal"],"backgroundTag":"unsupported-source-type","analyzedSha":"9f775e8a12daef8255556097396f9b2739078892","analyzedAt":"2026-09-19T03:17:15.984Z","contentChangedAt":"2026-09-19T03:17:15.984Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}