AlistGo/alist · warning

failed to encode thumbnail: %w

Error message

failed to encode thumbnail: %w

What it means

imaging.Encode failed while writing the resized thumbnail as JPEG (with JPEGQuality(quality)) into an in-memory bytes.Buffer. Encoding to a bytes.Buffer almost never fails on I/O; the realistic causes are quality values outside 1-100 confusing the encoder, or an image with an alpha channel/odd dimensions producing an encode error in the underlying image/jpeg package.

Source

Thrown at drivers/local/util.go:144

	if err != nil {
		return nil, fmt.Errorf("failed to decode image: %w", err)
	}

	thumbImg := imaging.Resize(img, targetWidth, 0, imaging.Lanczos)
	img = nil

	var buf bytes.Buffer
	// imaging.Encode
	// imaging.PNG, imaging.JPEG, imaging.GIF, imaging.BMP, imaging.TIFF
	outputFormat := imaging.JPEG
	encodeOptions := []imaging.EncodeOption{imaging.JPEGQuality(quality)}

	// outputFormat := imaging.PNG
	// encodeOptions := []imaging.EncodeOption{}

	err = imaging.Encode(&buf, thumbImg, outputFormat, encodeOptions...)
	if err != nil {
		return nil, fmt.Errorf("failed to encode thumbnail: %w", err)
	}

	thumbImg = nil

	return &buf, nil
}

// Get the snapshot of the video
func (d *Local) GetSnapshot(videoPath string) (imgData *bytes.Buffer, err error) {
	sanitized, err := sanitizeFilePath(videoPath)
	if err != nil {
		return nil, fmt.Errorf("invalid video path: %w", err)
	}
	videoPath = sanitized

	// Run ffprobe to get the video duration
	jsonOutput, err := ffmpeg.Probe(videoPath)
	if err != nil {

View on GitHub (pinned to 843d9dc814)

Solutions

  1. Clamp quality to [1,100] with a sane default (e.g. 85) before calling the helper
  2. Verify targetWidth > 0 before resizing
  3. Inspect the wrapped error from image/jpeg — 'invalid quality' or memory errors point to the two cases above

Example fix

// before: quality passed through unvalidated
encodeOptions := []imaging.EncodeOption{imaging.JPEGQuality(quality)}

// after: clamp to a valid range
if quality < 1 || quality > 100 {
    quality = 85
}
encodeOptions := []imaging.EncodeOption{imaging.JPEGQuality(quality)}
Defensive patterns

Strategy: validation

Validate before calling

func clampQuality(q int) int {
    if q < 1 || q > 100 {
        return 85
    }
    return q
}

Try / catch

Encode into bytes.Buffer failures are effectively bug indicators; log with the wrapped jpeg error and fall back to PNG encoding (imaging.PNG) which never fails on quality.

Prevention

When it happens

Trigger: Calling the helper with quality <= 0 or > 100; resizing produced a zero-width image because targetWidth <= 0 and imaging.Resize returned a degenerate image; extremely large images exceeding memory during encode.

Common situations: Driver configuration exposing a 'thumbnail quality' field where 0 (unset int) slips through as an actual quality value instead of a default; custom builds that change the default thumb quality constant.

Related errors


AI-assisted analysis of AlistGo/alist@843d9dc814 (2026-08-15). Data as JSON: /api/errors/58b867b644e9b0f0. Report an issue: GitHub.