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
FloatColorChannel::fromNormalized() maps a value in the closed interval [0.0, 1.0] onto the channel's internal range, and rejects anything outside it. This is the base factory for float channels such as alpha, so the check fires whenever a 'normalized' value is actually a percentage (e.g. 50 instead of 0.5), a negative number, or a float that drifted slightly past 1.0 through arithmetic.
Source
Thrown at src/Colors/FloatColorChannel.php:29
/**
* @throws InvalidArgumentException
*/
final public function __construct(float $value)
{
$this->value = (float) $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(static::min() + $normalized * (static::max() - static::min()));
}
/**
* {@inheritdoc}
*
* @see ColorChannelInterface::value()
*/
public function value(): float
{
return (float) $this->value;
}
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Divide percentages by 100 before calling fromNormalized()
- Clamp before calling: $value = min(1.0, max(0.0, $value))
- Guard division: if ($total <= 0) { $ratio = 0.0; } else { $ratio = $part / $total; }
- Round tiny float artifacts: $value = round($value, 6) before the call
Example fix
// before $alpha = Alpha::fromNormalized($userOpacity * 100); // 0-100 scale passed as normalized // after $alpha = Alpha::fromNormalized($userOpacity); // already 0.0-1.0 // or convert explicitly: $alpha = Alpha::fromNormalized($percent / 100);
Defensive patterns
Strategy: validation
Validate before calling
$normalized = min(1.0, max(0.0, $normalized));
if (!is_finite($normalized)) {
$normalized = 0.0;
}
$channel = Alpha::fromNormalized($normalized); Type guard
function isNormalizedValue(mixed $value): bool
{
return is_float($value) && is_finite($value) && $value >= 0.0 && $value <= 1.0;
} Prevention
- Decide on ONE alpha scale (0.0-1.0) across your domain and convert at the edges
- Clamp after any ratio math: min(1.0, max(0.0, $ratio))
- Guard divisions by zero before computing normalized values
When it happens
Trigger: Calling Alpha::fromNormalized(50) after forgetting to divide a percentage by 100; passing a ratio computed as $part / $total when $total is 0 (gives NAN) or when the parts sum to more than the total (ratio > 1); accumulating float rounding like 0.1 + 0.2 * 5 yielding 1.0000000000000002.
Common situations: Mixing up percent (0-100) and normalized (0-1) scales when bridging UI sliders, database values, or CSS percentages into the library; unvalidated external input; statistical normalization code where sums can exceed the divisor due to rounding.
Related errors
- 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
- Failed to import color {colorClass} to {class}
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/599eff5f1281e7d9.
Report an issue: GitHub.