Intervention/image · error · Intervention\Image\Exceptions\InvalidArgumentException
Normalized color channel value must be between 0 to 1
Error message
Normalized color channel value must be between 0 to 1
What it means
IntegerColorChannel::fromNormalized() only accepts a float between 0 and 1 inclusive, because a normalized value is a fraction of the channel's full range, not the channel value itself (src/Colors/IntegerColorChannel.php:26-35). This method is the base for all integer channels (RGB red/green/blue 0-255, CMYK 0-100, HSV hue 0-360 / saturation / value 0-100, HSL), so passing anything outside [0, 1.0] throws InvalidArgumentException.
Source
Thrown at src/Colors/IntegerColorChannel.php:29
/**
* @throws InvalidArgumentException
*/
final public function __construct(int $value)
{
$this->value = (int) $this->validValueOrFail($value);
}
/**
* {@inheritdoc}
*
* @see ColorChannelInterface::fromNormalized()
*
* @throws InvalidArgumentException
*/
public static function fromNormalized(float $normalized): self
{
if ($normalized < 0 || $normalized > 1) {
throw new InvalidArgumentException(
'Normalized color channel value must be between 0 to 1',
);
}
return new static(intval(round($normalized * static::max())));
}
/**
* {@inheritdoc}
*
* @see ColorChannelInterface::value()
*/
public function value(): int
{
return (int) $this->value;
}
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Divide by the channel maximum (e.g. 128 / 255) or use channel->normalized() to produce the fraction
- Clamp before calling: max(0.0, min(1.0, $value))
- Construct the channel with its real value instead: new Red(128), which validates against 0-255
- When building whole colors from normalized arrays, prefer Colorspace::colorFromNormalized() so alpha defaults are handled
Example fix
// before $channel = Rgb\Channels\Red::fromNormalized(128); // throws: must be between 0 to 1 // after $channel = Rgb\Channels\Red::fromNormalized(128 / 255); // or with the raw integer value: $channel = new Rgb\Channels\Red(128);
Defensive patterns
Strategy: validation
Validate before calling
function clamp01(float $v): float { return max(0.0, min(1.0, $v)); }
$channel = Rgb\Channels\Red::fromNormalized(clamp01($pixel / 255)); Type guard
function isNormalizedValue(mixed $value): bool
{
return is_float($value) && $value >= 0.0 && $value <= 1.0;
} Prevention
- Remember 'normalized' means 0..1, never 0..100 or the raw channel value
- Always divide by the channel max (255, 100, 360) before calling fromNormalized
- Clamp computed ratios before passing them to color APIs
When it happens
Trigger: Calling Red::fromNormalized(128) instead of Red::fromNormalized(128 / 255), Hsv\Channels\Saturation::fromNormalized(50) instead of 0.5, or passing a negative float; also hit indirectly when a colorspace's colorFromNormalized() receives out-of-range normalized values.
Common situations: Treating 'normalized' as a percentage (0-100) or as the raw channel value; computing ratios that can go slightly negative or above 1 due to float arithmetic or user math without clamping.
Related errors
- Normalized color channel value must be between 0 to 1
- Number of color channels must be 3 or 4 for {class}
- Normalized color value must be in range 0 to 1
- Number of color channels must be 3 or 4 for {class}
- Normalized color value must be in range 0 to 1
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/fe7dc9d11baa363d.
Report an issue: GitHub.