{"record":{"id":"b6188aceca3b72ee","repo":"Intervention/image","slug":"quantization-limit-must-be-greater-than-0","errorCode":null,"errorMessage":"Quantization limit must be greater than 0","messagePattern":"Quantization limit must be greater than 0","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Gd/Modifiers/ReduceColorsModifier.php","lineNumber":32,"sourceCode":"use Intervention\\Image\\Colors\\Rgb\\Color as RgbColor;\nuse Intervention\\Image\\Exceptions\\DriverException;\n\nclass ReduceColorsModifier extends GenericReduceColorsModifier implements SpecializedInterface\n{\n    /**\n     * {@inheritdoc}\n     *\n     * @see ModifierInterface::apply()\n     *\n     * @throws InvalidArgumentException\n     * @throws StateException\n     * @throws ModifierException\n     * @throws DriverException\n     */\n    public function apply(ImageInterface $image): ImageInterface\n    {\n        if ($this->limit <= 0) {\n            throw new InvalidArgumentException('Quantization limit must be greater than 0');\n        }\n\n        // no color reduction if the limit is higher than the colors in the img\n        $colorCount = imagecolorstotal($image->core()->native());\n        if ($colorCount > 0 && $this->limit > $colorCount) {\n            return $image;\n        }\n\n        $width = $image->width();\n        $height = $image->height();\n        $backgroundColor = $this->backgroundColor($image);\n\n        if (!$backgroundColor instanceof RgbColor) {\n            throw new ModifierException('Failed to convert background color to RGB color space');\n        }\n\n        $nativeBackgroundColor = $this->driver()\n            ->colorProcessor($image)","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Gd/Modifiers/ReduceColorsModifier.php#L14-L50","documentation":"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.","triggerScenarios":"$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.","commonSituations":"User-configurable palette sizes with 0 as an 'unlimited' sentinel; dynamic limits from histogram analysis; unvalidated form inputs reaching the image pipeline.","solutions":["Pass a limit of at least 1 (typical range 2-256)","Clamp dynamic values: $image->reduceColors(max(1, $computedLimit))","Treat 0 as 'no reduction' in your own code and skip the call entirely","Catch Intervention\\Image\\Exceptions\\InvalidArgumentException at the pipeline boundary"],"exampleFix":"// before: computed limit can reach 0\n$limit = count($palette) - 1;\n$image->reduceColors($limit);\n\n// after\n$limit = max(1, count($palette) - 1);\n$image->reduceColors($limit);","handlingStrategy":"validation","validationCode":"$limit = $userProvidedLimit; // e.g. from config or request\n\nif (!is_int($limit) || $limit < 1) {\n    throw new InvalidArgumentException('Color limit must be an integer >= 1');\n}\n\n$image->reduceColors($limit);","typeGuard":"function isValidQuantizationLimit(mixed $limit): bool\n{\n    return is_int($limit) && $limit >= 1;\n}","tryCatchPattern":"use Intervention\\Image\\Exceptions\\InvalidArgumentException;\n\ntry {\n    $image->reduceColors($limit);\n} catch (InvalidArgumentException $e) {\n    $image->reduceColors(256); // sane default\n}","preventionTips":["Clamp user/config-driven limits with max(1, $limit) before calling reduceColors().","Map sentinel values like 0 ('auto'/'unlimited') to skipping the call, not to the API.","Validate numeric settings at the boundary (form/config load), not inside image logic."],"tags":["gd","reduce-colors","quantization","limit","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}