{"record":{"id":"c5496bddac781c61","repo":"Intervention/image","slug":"quantization-levels-value-must-be-between-1-and-25","errorCode":null,"errorMessage":"Quantization levels value must be between 1 and 256","messagePattern":"Quantization levels value must be between 1 and 256","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Colors/Palette.php","lineNumber":458,"sourceCode":"    /**\n     * {@inheritdoc}\n     *\n     * @see PaletteInterface::hasColor()\n     */\n    public function hasColor(ColorInterface $color): bool\n    {\n        return array_key_exists($this->hashColor($color), $this->bins);\n    }\n\n    /**\n     * Quantize given color to number of levels.\n     *\n     * @throws InvalidArgumentException\n     */\n    private function quantizeColor(ColorInterface $color, int $levels): ColorInterface\n    {\n        if ($levels < 1 || $levels > 256) {\n            throw new InvalidArgumentException('Quantization levels value must be between 1 and 256');\n        }\n\n        // preserve alpha unquantized\n        $alpha = $color->alpha()->normalized();\n\n        // normalized channel values\n        $normalized = array_map(\n            fn(ColorChannelInterface $channel): float => $channel->normalized(),\n            $color->channels(),\n        );\n\n        // normalized channel values to bin index\n        $quantized = array_map(\n            function (float $normalized) use ($levels): int {\n                $bin = (int) floor($normalized * $levels); // 1.0 belongs to the last bin.\n                return min($bin, $levels - 1);\n            },\n            $normalized,","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Colors/Palette.php#L440-L476","documentation":"Palette::quantize() and Palette::reduce() both delegate to the private quantizeColor(), which maps each color channel onto a fixed number of discrete levels. The binning math only works for 1 to 256 levels (256 equals one level per 8-bit step), so any other integer (0, negative, or above 256) throws InvalidArgumentException before any color is processed.","triggerScenarios":"$palette->quantize(0), $palette->quantize(257), $palette->reduce(-1), or passing a computed level count such as count($colors) + 300 without clamping.","commonSituations":"Exposing the level value to end users or a config file without bounds checking; off-by-one loops like for ($i = 0; $i <= 257; $i++); confusing 'reduce the palette to N colors' (use sortByPresence() + slice()) with 'quantize to N levels'.","solutions":["Clamp the value before calling: $levels = max(1, min(256, $levels))","Validate user/config input against the 1..256 range and reject early with your own error","If you meant 'keep only N dominant colors', use $palette->sortByPresence()->slice(0, N) instead of quantize()"],"exampleFix":"// before\n$palette->quantize($request->integer('levels')); // 0 or 300 passed by user\n\n// after\n$levels = max(1, min(256, $request->integer('levels')));\n$palette->quantize($levels);","handlingStrategy":"validation","validationCode":"$levels = max(1, min(256, (int) $input));\nif ($levels < 1 || $levels > 256) {\n    throw new \\OutOfRangeException('levels must be 1..256');\n}\n$palette->quantize($levels);","typeGuard":null,"tryCatchPattern":"try {\n    $palette->quantize($levels);\n} catch (\\Intervention\\Image\\Exceptions\\InvalidArgumentException $e) {\n    $palette->quantize(16); // retry with a known-safe level count\n}","preventionTips":["Clamp quantization levels to 1..256 at every entry point (config, request, CLI)","Use sortByPresence()->slice(0, N) when you want N dominant colors, not quantize(N)","Write a boundary test asserting quantize(1) and quantize(256) both succeed"],"tags":["palette","quantization","validation","php"],"backgroundTag":"argument-out-of-range","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}