siyuan-note/siyuan · error
decode HEIF image
Error message
decode HEIF image: %v
What it means
decodeImage recovers a panic from the vendored goheic decoder and converts it into this error ("decode HEIF image: %v" with the recovered value). This keeps malformed or hostile HEIF bitstreams from crashing the kernel with a panic. The %v formatting means the original panic value is not wrapped — match by prefix, not errors.Is.
Solutions
- Treat the source file as corrupt: re-export/re-import the image from the original device
- Inspect the recovered panic message to identify whether it is a known goheic limitation
- Isolate the failing asset and reproduce with goheic directly; report upstream if it is a decoder bug
Example fix
// before
img, err := heif.ImageSize(data) // panics propagate in naive wrappers
// after
if _, err := heif.ImageSize(data); err != nil {
if strings.HasPrefix(err.Error(), "decode HEIF image:") {
return fmt.Errorf("asset is corrupt or unsupported HEIF: %v", err)
}
return err
} Defensive patterns
Strategy: try-catch
Validate before calling
// heuristically pre-validate the container magic before decode
if !bytes.Contains(data[:12], []byte("ftyp")) {
return fmt.Errorf("not a HEIF container")
} Try / catch
if _, err := heif.ImageSize(data); err != nil {
if strings.HasPrefix(err.Error(), "decode HEIF image:") {
// decoder panicked on this input; treat as corrupt, never retry blindly
return fmt.Errorf("corrupt HEIF asset: %v", err)
}
} Prevention
- Never feed untrusted/truncated HEIF bytes directly; the package recovers panics but the asset is still bad
- Sanitize imported assets (re-encode via a trusted tool)
- Keep goheic updated to reduce panic-triggering decoder bugs
When it happens
Trigger: goheic.DecodeBytes (or related code inside decodeImage) panics on a corrupt, truncated, or malformed HEIF payload; the recover in decodeImage fires and returns this error.
Common situations: Fuzzed or corrupted .heic assets, files with valid headers but broken compressed payloads, goheic library bugs on exotic HEIF profiles (e.g. multi-image or depth maps).
Related errors
- decode HEIF image
- read HEIF image dimensions
- avif: exif data too short
- decode image failed
- empty HEIF image
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/75c3a455bb78cf36.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/heif/convert.go:180
defer func() {
<-conversionSlots
}()
img, err := decodeImage(source)
if err != nil {
return 0, 0, err
}
width, height = img.Bounds().Dx(), img.Bounds().Dy()
if !validDimensions(width, height) {
return 0, 0, ErrImageTooLarge
}
return width, height, nil
}
func decodeImage(source []byte) (img image.Image, err error) {
defer func() {
if recovered := recover(); recovered != nil {
img = nil
err = fmt.Errorf("decode HEIF image: %v", recovered)
}
}()
config, err := goheic.DecodeConfigBytes(source)
if err != nil {
return nil, fmt.Errorf("read HEIF image dimensions: %w", err)
}
if !validDimensions(config.Width, config.Height) {
return nil, ErrImageTooLarge
}
img, err = goheic.DecodeBytes(source, goheic.Options{
AutoRotate: true,
FrameSizeLimit: maxPixels,
Threads: 1,
})
if err != nil {
return nil, fmt.Errorf("decode HEIF image: %w", err)View on GitHub (pinned to 9f775e8a12)