Billionmail/BillionMail · error
imagemagick thumbnail failed: %w output: %s
Error message
imagemagick thumbnail failed: %w output: %s
What it means
GenerateThumbnail shells out to ImageMagick's 'magick' CLI via exec.CommandContext to produce a video thumbnail, capturing combined stdout/stderr. When the command exits non-zero (or the binary cannot be found/executed), the underlying error is wrapped as 'imagemagick thumbnail failed: %w' with the full CLI output appended, so both the Go-level failure and ImageMagick's own diagnostics are preserved in one message.
Source
Thrown at core/internal/service/video_gen/thumbnail.go:65
cfg.InputPath,
"-resize", fmt.Sprintf("%dx%d!", w, h),
"-quality", "90",
cfg.OutputPath,
}
}
// GenerateThumbnail creates a thumbnail from a screenshot using ImageMagick.
// Requires: magick (ImageMagick) installed.
func GenerateThumbnail(ctx context.Context, cfg ThumbnailConfig) (string, error) {
if err := os.MkdirAll(filepath.Dir(cfg.OutputPath), 0755); err != nil {
return "", fmt.Errorf("create thumbnail dir: %w", err)
}
args := BuildThumbnailArgs(cfg)
cmd := exec.CommandContext(ctx, "magick", args...)
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("imagemagick thumbnail failed: %w\noutput: %s", err, string(out))
}
return cfg.OutputPath, nil
}
View on GitHub (pinned to fc36c76c05)
Solutions
- Install ImageMagick (apt-get install imagemagick / apk add imagemagick) and confirm 'magick -version' works inside the container
- Run the exact args from BuildThumbnailArgs(cfg) by hand to inspect ImageMagick's output printed after 'output:' in the error
- Verify the input video path exists and is readable before calling GenerateThumbnail
- If running ImageMagick 6, either upgrade to IM7 or adapt BuildThumbnailArgs to invoke 'convert'
- Check context cancellation: if the pipeline is being shut down, the wrapped error will be context.Canceled
Example fix
// before
cmd := exec.CommandContext(ctx, "magick", args...)
out, err := cmd.CombinedOutput()
// after
if _, err := exec.LookPath("magick"); err != nil {
return "", fmt.Errorf("imagemagick not found on PATH: %w", err)
}
cmd := exec.CommandContext(ctx, "magick", args...)
out, err := cmd.CombinedOutput() Defensive patterns
Strategy: validation
Validate before calling
if _, err := exec.LookPath("magick"); err != nil {
return fmt.Errorf("thumbnail prerequisite missing: install imagemagick: %w", err)
}
if info, err := os.Stat(inputVideoPath); err != nil || info.IsDir() {
return fmt.Errorf("input video not readable: %s", inputVideoPath)
}
if ctx.Err() != nil {
return ctx.Err()
} Try / catch
urls, err := GenerateThumbnail(ctx, cfg)
if err != nil {
var execErr *exec.ExitError
switch {
case errors.Is(err, context.Canceled):
// pipeline shutdown; do not retry
case errors.As(err, &execErr):
log.Errorf("magick failed: %v", err) // output is embedded in the message
default:
log.Errorf("thumbnail error: %v", err)
}
} Prevention
- Bake imagemagick into the deployment image and check 'magick -version' at container startup
- Add an exec.LookPath('magick') preflight in service init
- Always stat input files before invoking GenerateThumbnail
- Keep BuildThumbnailArgs covered by unit tests so arg changes fail fast
When it happens
Trigger: magick is not installed or not on PATH (exec.ErrNotFound via CombinedOutput); the input video path does not exist or is unreadable (as tested by TestGenerateThumbnail_NonexistentInput); the supplied thumbnail args are malformed; or the context is cancelled before magick finishes (TestGenerateThumbnail_CancelledContext), causing Wait to fail with a context/deadline error.
Common situations: Minimal Docker images without imagemagick installed; ImageMagick 6 environments that ship the binary as 'convert' instead of 'magick'; video files in formats magick cannot delegate to ffmpeg; missing file permissions; pipeline shutdown cancelling the context mid-conversion.
Related errors
- imagemagick annotate failed: %w\noutput: %s
- annotate %s: %w
- ffmpeg compositing failed: %w\noutput: %s
- rar compression failed: %s - %s
- rar file was not created successfully
AI-assisted analysis of Billionmail/BillionMail@fc36c76c05 (2026-09-05).
Data as JSON: /api/errors/d8568a15c45c0aed.
Report an issue: GitHub.