{"record":{"id":"a916b85b345ebe0d","repo":"siyuan-note/siyuan","slug":"unsupported-or-invalid-image-s","errorCode":null,"errorMessage":"unsupported or invalid image: %s","messagePattern":"unsupported or invalid image: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/util/openai.go","lineNumber":755,"sourceCode":"func 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,\n\t\t\tMIMEType:   mimeType,\n\t\t\tWidth:      bounds.Dx(),\n\t\t\tHeight:     bounds.Dy(),\n\t\t\tSourceSize: len(data),","sourceCodeStart":737,"sourceCodeEnd":773,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/util/openai.go#L737-L773","documentation":"After the MIME check, PrepareModelImage calls image.DecodeConfig to cheaply read the image header. If decoding fails (corrupt file, truncated data, or a format with no registered decoder), it wraps the underlying reason in this error. It distinguishes 'the bytes are not a decodable image' from the earlier format-allowlist errors.","triggerScenarios":"Calling PrepareModelImage with truncated or corrupt image data, a file that passes MIME sniffing but has a broken header, or a format whose Go decoder was not linked into the binary.","commonSituations":"Partially downloaded assets; files corrupted on disk or in sync; images with valid extensions but garbage content; zero-dimension or otherwise malformed headers.","solutions":["Re-download or re-copy the image from its source — the file is likely corrupt or truncated","Open the file in an image viewer to confirm it is valid before sending it to the model","Check disk/sync integrity for the asset (possibly re-sync the workspace)","Verify the backend links the needed image decoders if you extended supported formats"],"exampleFix":"// before: no integrity check\nprepared, err := PrepareModelImage(data, maxBytes, maxPixels, maxEdge)\n// after: fail fast on truncated files\nif fi, e := os.Stat(path); e != nil || fi.Size() == 0 {\n    return errors.New(\"asset missing or empty: \" + path)\n}\nprepared, err := PrepareModelImage(data, maxBytes, maxPixels, maxEdge)","handlingStrategy":"validation","validationCode":"if _, _, err := image.DecodeConfig(bytes.NewReader(data)); err != nil {\n    return fmt.Errorf(\"asset is not a decodable image: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"prepared, err := PrepareModelImage(data, maxBytes, maxPixels, maxEdge)\nif err != nil && strings.Contains(err.Error(), \"unsupported or invalid image\") {\n    log.Warnf(\"asset corrupt, re-fetching: %v\", err)\n    return reDownloadAsset()\n}","preventionTips":["Verify assets after download/sync (size and header check) before use","Treat this error as data corruption: re-download or re-export rather than retry","Keep source copies of images outside the workspace for recovery","Validate files copied between devices or through sync"],"tags":["image","decode","corrupt-file","validation"],"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"}