siyuan-note/siyuan · error
decode HEIF image: %v
Error message
decode HEIF image: %v
What it means
decodeImage recovers a panic from the internal HEIC decoder (which wraps cgo/libheif-style native code) and converts it into this error carrying the recovered value. Native decoders can panic (or crash) on malformed bitstreams, so the package deliberately converts panics into ordinary errors to protect the process.
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 8641553a1f)
Solutions
- Treat the file as unrenderable and surface a user-facing 'cannot open this image' message
- Check the recovered value in the message to see whether it is an out-of-range panic, nil deref, or native assertion
- Verify the file opens in another HEIF viewer; if not, the file is corrupt
- Report the file to maintainers if it decodes elsewhere — it may expose a decoder bug needing an upstream fix
- Consider re-encoding the image with an external tool before importing
Defensive patterns
Strategy: try-catch
Validate before calling
if len(source) < 12 || string(source[4:8]) != "ftyp" {
return errors.New("not a HEIF container")
} Type guard
func looksLikeHeif(b []byte) bool {
return len(b) >= 12 && string(b[4:8]) == "ftyp"
} Try / catch
if err != nil && strings.HasPrefix(err.Error(), "decode HEIF image:") {
log.Warnf("decoder panicked on HEIF input: %v", err)
return errUnsupportedFile
} Prevention
- Validate the ftyp brand before handing bytes to the decoder
- Quarantine files that repeatedly panic and skip them in batch jobs
- Report panic-inducing files upstream so the native parser gets fixed
- Run batch conversions with per-file error isolation, not fail-fast
When it happens
Trigger: Any call path that reaches decodeImage — convert (ModePreview/ModeThumbnail) or ImageSize — where the internal decoder panics while parsing the HEIF/HEVC bitstream, e.g. malformed NAL units, corrupt VPS/SPS/PPS, or out-of-bounds access in native parsing.
Common situations: Corrupt or deliberately fuzzed .heic files; partially downloaded/truncated assets; files renamed to .heic that are not actually HEIF; unusual HEVC profiles the decoder mishandles.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- read HEIF image dimensions: %w
- encrypted HEIF cache requires a notebook ID
- empty HEIF image
- ErrInputTooLarge
- ErrImageTooLarge
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/75c3a455bb78cf36.
Report an issue: GitHub.