{"record":{"id":"88a6847d1525d5e2","repo":"siyuan-note/siyuan","slug":"decode-image-failed-s","errorCode":null,"errorMessage":"decode image failed: %s","messagePattern":"decode image failed: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":763,"sourceCode":"\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,\n\t\t\tMIMEType:   mimeType,\n\t\t\tWidth:      bounds.Dx(),\n\t\t\tHeight:     bounds.Dy(),\n\t\t\tSourceSize: len(data),\n\t\t}, nil\n\t}\n\tif needsResize {\n\t\tdecoded = imaging.Fit(decoded, maxEdge, maxEdge, imaging.Lanczos)\n\t}\n\tbounds = decoded.Bounds()\n\tif mimeType == \"image/png\" || mimeType == \"image/webp\" {\n\t\tvar output bytes.Buffer","sourceCodeStart":745,"sourceCodeEnd":781,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/openai.go#L745-L781","documentation":"PrepareModelImage wraps the disintegration/imaging library's Decode failure with the message \"decode image failed: %s\" (kernel/util/openai.go:763). The data has already passed magic-byte MIME detection and DecodeConfig checks, so this error means the full pixel decode (with EXIF auto-orientation) failed — typically a truncated, corrupted, or partially-downloaded image whose header parsed fine but whose body does not.","triggerScenarios":"Calling PrepareModelImage with image bytes whose header is valid enough for mimetype.Detect and image.DecodeConfig but which fail full decoding: truncated files, corrupted pixel data, unsupported CMYK/YCbCr edge cases, or a format the imaging library cannot handle even though the kernel registered a decoder for it.","commonSituations":"Downloads interrupted mid-transfer; assets modified or partially written to disk; clipboard-saved image fragments; an image whose earlier DecodeConfig succeeded (headers intact) but the trailing chunks are damaged; registering a format decoder (e.g. webp) that decodes configs but not full images in the imaging library.","solutions":["Re-obtain or re-download the image file; verify the source file opens in a normal image viewer and is not truncated.","Inspect the wrapped underlying error in the message to identify the exact decoder failure (e.g. 'short Huffman data', 'unexpected EOF').","Re-encode the image once with a standard tool (e.g. convert to PNG/JPEG) before sending it to a multimodal model.","If the format is exotic (progressive/lossless webp variants, 16-bit PNG), convert it to a baseline JPEG or PNG first."],"exampleFix":"// before: sending raw bytes read from an interrupted download\nprepared, err := util.PrepareModelImage(data, maxBytes, maxPixels, maxEdge)\n\n// after: verify the image fully decodes before use\nif _, err := imaging.Decode(bytes.NewReader(data)); err != nil {\n    // re-download or re-encode the source image\n}\nprepared, err := util.PrepareModelImage(data, maxBytes, maxPixels, maxEdge)","handlingStrategy":"validation","validationCode":"func isDecodableImage(data []byte) bool {\n    _, err := imaging.Decode(bytes.NewReader(data), imaging.AutoOrientation(true))\n    return err == nil\n}","typeGuard":null,"tryCatchPattern":"prepared, err := util.PrepareModelImage(data, maxBytes, maxPixels, maxEdge)\nif err != nil && strings.HasPrefix(err.Error(), \"decode image failed\") {\n    // re-download/re-encode the source before giving up\n}","preventionTips":["Verify downloaded images are complete (compare Content-Length or checksum) before processing","Re-encode images from untrusted or network sources to baseline PNG/JPEG before passing them in","Handle partial writes atomically: never process an image file while it is still being written"],"tags":["image-processing","decode-failed","corrupt-image"],"backgroundTag":"invalid-argument-format","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}