{"record":{"id":"18c1cc7e50ec462c","repo":"Intervention/image","slug":"color-channel-class-value-must-be-in-range-min","errorCode":null,"errorMessage":"Color channel {class} value must be in range {min} to {max}","messagePattern":"Color channel (.+?) value must be in range (.+?) to (.+?)","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Colors/AbstractColorChannel.php","lineNumber":62,"sourceCode":"\n        $normalized = $this->normalized();\n        $base = $percent >= 0 ? (1 - $normalized) : $normalized;\n        $scaled = min(1.0, max(0.0, $normalized + $base / 100 * $percent));\n        $this->value = static::fromNormalized($scaled)->value();\n\n        return $this;\n    }\n\n    /**\n     * Throw exception if the given value is not applicable for channel\n     * otherwise the value is returned unchanged.\n     *\n     * @throws InvalidArgumentException\n     */\n    protected function validValueOrFail(int|float $value): mixed\n    {\n        if ($value < $this->min() || $value > $this->max()) {\n            throw new InvalidArgumentException(\n                'Color channel ' . $this::class . ' value must be in range ' . $this->min() . ' to ' . $this->max(),\n            );\n        }\n\n        return $value;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see ColorChannelInterface::toString()\n     */\n    public function toString(): string\n    {\n        return (string) $this->value();\n    }\n\n    /**","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Colors/AbstractColorChannel.php#L44-L80","documentation":"DrawPolygonModifier requires the Polygon it receives to contain at least 3 points, because a polygon with fewer vertices cannot be rasterized. The check runs in the constructor, so $image->drawPolygon() fails immediately when handed a degenerate Polygon.","triggerScenarios":"$image->drawPolygon(new Polygon($points)) where $points has 0-2 entries; building points dynamically from data that can collapse (filtered results, empty datasets, division producing coincident points reduced by dedup).","commonSituations":"Chart/map overlays where a region's coordinates come from a database query that returned one row; array_filter() removing invalid points below the threshold; empty input arrays from failed upstream parsing.","solutions":["Count before drawing: if ($polygon->count() >= 3) { $image->drawPolygon($polygon); }.","Skip or log degenerate datasets instead of drawing them.","If points were removed by validation, treat fewer than 3 remaining points as 'nothing to draw', not as a draw call."],"exampleFix":"// before\n$image->drawPolygon($polygon); // count() === 2 throws\n\n// after\nif ($polygon->count() >= 3) {\n    $image->drawPolygon($polygon);\n}","handlingStrategy":"validation","validationCode":"if ($polygon->count() < 3) {\n    // nothing drawable; skip or log\n    return;\n}\n$image->drawPolygon($polygon);","typeGuard":"function isDrawablePolygon(Intervention\\Image\\Geometry\\Polygon $polygon): bool\n{\n    return $polygon->count() >= 3;\n}","tryCatchPattern":null,"preventionTips":["Check count() >= 3 whenever points come from filtering or external data.","Treat degenerate geometry as a no-op in renderers.","Guard the data source: require at least 3 coordinate rows before building the Polygon."],"tags":["polygon","drawing","argument-validation","modifier","php"],"backgroundTag":"invalid-geometry","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}