Intervention/image · error · ColorDecoderException
Failed to decode RGB color string
Error message
Failed to decode RGB color string
What it means
The rgb()/rgba() string matched the CSS syntax regex in StringColorDecoder, but constructing the Color object from the extracted numbers failed. This means the syntax was recognized yet a value is out of range: an RGB channel outside 0-255 or an alpha outside 0.0-1.0. The original InvalidArgumentException from the Color constructor is chained as the previous exception and names the offending value.
Source
Thrown at src/Colors/Rgb/Decoders/StringColorDecoder.php:75
// rgb values
$values = array_map(fn(string $value): int => match (strpos($value, '%')) {
false => intval(trim($value)),
default => intval(round(floatval(trim(str_replace('%', '', $value))) / 100 * 255)),
}, [$matches['r'], $matches['g'], $matches['b']]);
// alpha value
if (array_key_exists('a', $matches)) {
$values[] = match (strpos($matches['a'], '%')) {
false => floatval(trim($matches['a'])),
default => floatval(trim(str_replace('%', '', $matches['a']))) / 100,
};
}
try {
return new Color(...$values);
} catch (InvalidArgumentException $e) {
throw new ColorDecoderException('Failed to decode RGB color string', previous: $e);
}
}
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Clamp channels to 0-255 and alpha to 0.0-1.0 before formatting the color string
- Inspect ->getPrevious() of the ColorDecoderException to see exactly which value the Color constructor rejected
- If you only need a guaranteed-parseable color, pass a hex string like '#ff0000' instead
Example fix
// before
$color = $manager->color('rgb(300, 12, 12)');
// after
$color = $manager->color(sprintf('rgb(%d, %d, %d)',
min(255, max(0, $r)),
min(255, max(0, $g)),
min(255, max(0, $b))
)); Defensive patterns
Strategy: validation
Validate before calling
function safeRgbString(int $r, int $g, int $b, float $a = 1.0): string
{
return sprintf(
'rgba(%d, %d, %d, %s)',
min(255, max(0, $r)),
min(255, max(0, $g)),
min(255, max(0, $b)),
min(1.0, max(0.0, $a))
);
} Try / catch
try {
$color = $driver->decodeColor($rgbString);
} catch (ColorDecoderException $e) {
// $e->getPrevious() carries the Color constructor error naming the bad value
$color = $driver->decodeColor('#ffffff');
} Prevention
- Clamp dynamic channel values to 0-255 and alpha to 0.0-1.0 before formatting rgb()/rgba() strings
- Prefer hex strings for programmatically generated colors
- Log ->getPrevious() when this fires - it names the exact offending value
When it happens
Trigger: Passing strings like 'rgb(300, 0, 0)' (channel above 255), 'rgba(255, 0, 0, 1.5)' (alpha above 1), or percentage values that resolve above 255 such as 'rgb(120%, 0%, 0%)' to any color-accepting API: fill(), text color, background color, or direct driver color decoding.
Common situations: Colors built dynamically from user input or a database without clamping; CSS values copied from design tools that permit out-of-range notation; percentage math that rounds above 255.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Invalid cmyk() color syntax "{input}"
- Unable to parse HSL color from input "{input}"
- Failed to import color {colorClass} to {class}
- Invalid hsl() color syntax "{input}"
- Unable to parse HSV color from input "{input}"
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/636603f5e4106f1a.
Report an issue: GitHub.