siyuan-note/siyuan · error
unsupported image type
Error message
unsupported image type: %s
What it means
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.
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
Example fix
// before prepared, err := PrepareModelImage(heicBytes, maxBytes, maxPixels, maxEdge) // "unsupported image type: image/heic" // after jpegBytes := convert(heicBytes, "image/jpeg") // transcode HEIC to JPEG first prepared, err := PrepareModelImage(jpegBytes, maxBytes, maxPixels, maxEdge)
Defensive patterns
Strategy: validation
Validate before calling
mt := mimetype.Detect(data).String()
if !isRasterImage(mt) { data = transcodeToJPEG(data) } Type guard
func isRasterImage(mt string) bool {
switch mt {
case "image/gif", "image/jpeg", "image/png", "image/webp":
return true
}
return false
} Try / catch
prepared, err := PrepareModelImage(data, maxBytes, maxPixels, maxEdge)
if err != nil && strings.Contains(err.Error(), "unsupported image type") {
prepared, err = PrepareModelImage(transcodeToJPEG(data), maxBytes, maxPixels, maxEdge)
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- decode image failed:
- encode image failed:
- image data is empty
- image exceeds size limit
- SVG images are not accepted by multimodal models
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/e28e5059d4fa8b4b.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/openai.go:775
return
}
// PrepareModelImage 校验并按需缩放图片,尽量保留多模态模型支持的原始格式和图片质量。
func PrepareModelImage(data []byte, maxBytes, maxPixels, maxEdge int) (PreparedImage, error) {
if len(data) == 0 {
return PreparedImage{}, errors.New("image data is empty")
}
if maxBytes > 0 && len(data) > maxBytes {
return PreparedImage{}, fmt.Errorf("image exceeds size limit: %d bytes", maxBytes)
}
mimeType := mimetype.Detect(data).String()
if strings.Contains(mimeType, "svg") || bytes.Contains(bytes.ToLower(data[:min(len(data), 512)]), []byte("<svg")) {
return PreparedImage{}, errors.New("SVG images are not accepted by multimodal models")
}
switch mimeType {
case "image/gif", "image/jpeg", "image/png", "image/webp":
default:
return PreparedImage{}, fmt.Errorf("unsupported image type: %s", mimeType)
}
config, _, err := image.DecodeConfig(bytes.NewReader(data))
if err != nil {
return PreparedImage{}, errors.New("unsupported or invalid image: " + err.Error())
}
if config.Width < 1 || config.Height < 1 || maxPixels > 0 && int64(config.Width)*int64(config.Height) > int64(maxPixels) {
return PreparedImage{}, fmt.Errorf("image exceeds pixel limit: %d", maxPixels)
}
decoded, err := imaging.Decode(bytes.NewReader(data), imaging.AutoOrientation(true))
if err != nil {
return PreparedImage{}, errors.New("decode image failed: " + err.Error())
}
bounds := decoded.Bounds()
needsResize := maxEdge > 0 && (bounds.Dx() > maxEdge || bounds.Dy() > maxEdge)
if !needsResize && bounds.Dx() == config.Width && bounds.Dy() == config.Height && mimeType != "image/gif" {
return PreparedImage{
Data: data,View on GitHub (pinned to 9f775e8a12)