Intervention/image · error · InvalidArgumentException

Quantization limit must be greater than 0

Error message

Quantization limit must be greater than 0

What it means

GD quantizes via imagetruecolortopalette(), which needs at least one color, so the GD apply() rejects limit <= 0 with InvalidArgumentException. Note the generic ReduceColorsModifier constructor already rejects limits < 1 at instantiation ('Invalid color limit. Must be int<1, max>'), so through the normal $image->reduceColors() API this exact message surfaces mainly when the modifier is stored/reused, mutated, or applied through a deferred pipeline.

Source

Thrown at src/Drivers/Gd/Modifiers/ReduceColorsModifier.php:32

use Intervention\Image\Colors\Rgb\Color as RgbColor;
use Intervention\Image\Exceptions\DriverException;

class ReduceColorsModifier extends GenericReduceColorsModifier implements SpecializedInterface
{
    /**
     * {@inheritdoc}
     *
     * @see ModifierInterface::apply()
     *
     * @throws InvalidArgumentException
     * @throws StateException
     * @throws ModifierException
     * @throws DriverException
     */
    public function apply(ImageInterface $image): ImageInterface
    {
        if ($this->limit <= 0) {
            throw new InvalidArgumentException('Quantization limit must be greater than 0');
        }

        // no color reduction if the limit is higher than the colors in the img
        $colorCount = imagecolorstotal($image->core()->native());
        if ($colorCount > 0 && $this->limit > $colorCount) {
            return $image;
        }

        $width = $image->width();
        $height = $image->height();
        $backgroundColor = $this->backgroundColor($image);

        if (!$backgroundColor instanceof RgbColor) {
            throw new ModifierException('Failed to convert background color to RGB color space');
        }

        $nativeBackgroundColor = $this->driver()
            ->colorProcessor($image)

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Pass a limit of at least 1 (typical range 2-256)
  2. Clamp dynamic values: $image->reduceColors(max(1, $computedLimit))
  3. Treat 0 as 'no reduction' in your own code and skip the call entirely
  4. Catch Intervention\Image\Exceptions\InvalidArgumentException at the pipeline boundary

Example fix

// before: computed limit can reach 0
$limit = count($palette) - 1;
$image->reduceColors($limit);

// after
$limit = max(1, count($palette) - 1);
$image->reduceColors($limit);
Defensive patterns

Strategy: validation

Validate before calling

$limit = $userProvidedLimit; // e.g. from config or request

if (!is_int($limit) || $limit < 1) {
    throw new InvalidArgumentException('Color limit must be an integer >= 1');
}

$image->reduceColors($limit);

Type guard

function isValidQuantizationLimit(mixed $limit): bool
{
    return is_int($limit) && $limit >= 1;
}

Try / catch

use Intervention\Image\Exceptions\InvalidArgumentException;

try {
    $image->reduceColors($limit);
} catch (InvalidArgumentException $e) {
    $image->reduceColors(256); // sane default
}

Prevention

When it happens

Trigger: $image->reduceColors(0) or a negative limit; runtime-computed limits that evaluate to 0, such as reduceColors(count($palette) - 1) with a one-color palette; 'colors' settings where 0 means 'auto' but is passed through unmapped.

Common situations: User-configurable palette sizes with 0 as an 'unlimited' sentinel; dynamic limits from histogram analysis; unvalidated form inputs reaching the image pipeline.

Related errors


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/b6188aceca3b72ee. Report an issue: GitHub.