siyuan-note/siyuan · error
encode image failed
Error message
encode image failed: %s
What it means
Thrown at kernel/util/openai.go:807 when re-encoding a decoded (and possibly resized) PNG or WebP image back to PNG via png.Encode fails. This is rare because PNG encoding of an in-memory NRGBA image seldom fails, but it can happen under memory exhaustion or with zero-size images.
Solutions
- Free memory / reduce concurrent image processing, or use a smaller source image
- Skip processing and send the original bytes if they are already within the byte limit
- Ensure the decoded image has non-zero bounds before encoding
- Retry the operation once memory pressure subsides
Example fix
// before: unconditional re-encode on any resize
if needsResize { decoded = imaging.Fit(decoded, maxEdge, maxEdge, imaging.Lanczos) }
out, err := reencodePNGorFail(decoded)
// after: reuse original bytes when no resize is actually needed
if !needsResize {
return useOriginalBytes(data)
}
decoded = imaging.Fit(decoded, maxEdge, maxEdge, imaging.Lanczos)
out, err := reencodePNGorFail(decoded) Defensive patterns
Strategy: try-catch
Validate before calling
if decoded.Bounds().Dx() < 1 || decoded.Bounds().Dy() < 1 {
return errors.New("cannot encode empty image")
} Try / catch
if err := encodePNG(&output, decoded); err != nil {
if isOOM(err) {
// fall back to original bytes or a smaller resize
return useOriginalOrSmaller(data)
}
return err
} Prevention
- Reuse original bytes whenever no resize is needed instead of re-encoding
- Bound source image sizes before decoding to limit encoder memory
- Ensure images have non-zero bounds before encoding
- Process images sequentially in memory-constrained environments
When it happens
Trigger: After resizing with imaging.Fit, encoding the resulting image to PNG fails (png.Encode returns a non-nil error) — typically out-of-memory on very large canvases or a degenerate zero-dimension image.
Common situations: Very large images combined with low available memory; images that decode to 0×0 bounds; resource-constrained environments where the encoder cannot allocate buffers.
Understand the failure class
Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.
Related errors
- decode image failed
- encode image failed:
- generated image exceeds size limit
- generated image is empty
- generated image is invalid
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/946a1fba26e51597.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/util/openai.go:807
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,
MIMEType: mimeType,
Width: bounds.Dx(),
Height: bounds.Dy(),
SourceSize: len(data),
}, nil
}
if needsResize {
decoded = imaging.Fit(decoded, maxEdge, maxEdge, imaging.Lanczos)
}
bounds = decoded.Bounds()
if mimeType == "image/png" || mimeType == "image/webp" {
var output bytes.Buffer
if err = png.Encode(&output, decoded); err != nil {
return PreparedImage{}, errors.New("encode image failed: " + err.Error())
}
if maxBytes <= 0 || output.Len() <= maxBytes {
return PreparedImage{
Data: output.Bytes(),
MIMEType: "image/png",
Width: bounds.Dx(),
Height: bounds.Dy(),
SourceSize: len(data),
}, nil
}
}
var output bytes.Buffer
if err = jpeg.Encode(&output, decoded, &jpeg.Options{Quality: 92}); err != nil {
return PreparedImage{}, errors.New("encode image failed: " + err.Error())
}
if maxBytes > 0 && output.Len() > maxBytes {
return PreparedImage{}, fmt.Errorf("prepared image exceeds size limit: %d bytes", maxBytes)
}View on GitHub (pinned to 9f775e8a12)