From a5ba90c5c9dfe3961a7f0573e986a35262a942e4 Mon Sep 17 00:00:00 2001 From: jamey Date: Sun, 1 Mar 2026 23:11:18 +0000 Subject: [PATCH] skip image optimization for tiny placeholder images Images under 100 bytes (e.g. 44-byte 1x1 pixel webp stubs from seeded data) crash libvips. Filter them at three levels: VariantCache skips them in the query, Optimizer returns :too_small, and OptimizeWorker cancels (not retries) the job to avoid activity log spam. Co-Authored-By: Claude Opus 4.6 --- lib/berrypod/images/optimize_worker.ex | 1 + lib/berrypod/images/optimizer.ex | 5 +++++ lib/berrypod/images/variant_cache.ex | 2 ++ 3 files changed, 8 insertions(+) diff --git a/lib/berrypod/images/optimize_worker.ex b/lib/berrypod/images/optimize_worker.ex index a52a2e5..9d0502a 100644 --- a/lib/berrypod/images/optimize_worker.ex +++ b/lib/berrypod/images/optimize_worker.ex @@ -29,6 +29,7 @@ defmodule Berrypod.Images.OptimizeWorker do {:ok, _} -> :ok {:error, :not_found} -> {:cancel, :image_not_found} {:error, :no_data} -> {:cancel, :no_image_data} + {:error, :too_small} -> {:cancel, :image_too_small} {:error, reason} -> {:error, reason} end end diff --git a/lib/berrypod/images/optimizer.ex b/lib/berrypod/images/optimizer.ex index 5780ca0..5443de5 100644 --- a/lib/berrypod/images/optimizer.ex +++ b/lib/berrypod/images/optimizer.ex @@ -13,6 +13,8 @@ defmodule Berrypod.Images.Optimizer do @thumb_size 200 @max_stored_width 2000 @storage_quality 90 + # Skip images smaller than this — they're placeholders or corrupt + @min_image_bytes 100 def cache_dir do Application.get_env(:berrypod, :image_cache_dir) || @@ -80,6 +82,9 @@ defmodule Berrypod.Images.Optimizer do Repo.update!(ImageSchema.changeset(image, %{variants_status: "complete"})) {:ok, :svg_skipped} + %{data: data} when byte_size(data) < @min_image_bytes -> + {:error, :too_small} + %{data: data, source_width: width} = image -> File.mkdir_p!(cache_dir()) diff --git a/lib/berrypod/images/variant_cache.ex b/lib/berrypod/images/variant_cache.ex index 8fdd761..f319385 100644 --- a/lib/berrypod/images/variant_cache.ex +++ b/lib/berrypod/images/variant_cache.ex @@ -52,10 +52,12 @@ defmodule Berrypod.Images.VariantCache do defp ensure_database_image_variants do # Only load IDs and source_width for the disk check — avoids loading BLOBs + # Skip tiny images (< 100 bytes) — they're placeholders that can't be processed incomplete_ids = ImageSchema |> where([i], i.variants_status != "complete" or is_nil(i.variants_status)) |> where([i], i.is_svg == false) + |> where([i], i.file_size >= 100) |> select([i], {i.id, i.source_width}) |> Repo.all()