Intervention/image · error · InvalidArgumentException
Invalid rgb() color syntax "{input}"
Error message
Invalid rgb() color syntax "{input}" What it means
StringColorDecoder::decode() validates the input against a strict rgb()/rgba() pattern: values must be 1-3 digit integers (or percentages), separated consistently by commas or spaces, with an optional alpha as 0-1 float or percentage. Its supports() accepts any string starting with 'rgb', so malformed rgb(...) strings reach decode() and fail the full pattern, throwing this InvalidArgumentException with the offending input echoed back.
Source
Thrown at src/Colors/Rgb/Decoders/StringColorDecoder.php:55
}
if (preg_match('/^s?rgb/i', $input) !== 1) {
return false;
}
return true;
}
/**
* Decode rgb color strings.
*
* @throws InvalidArgumentException
* @throws ColorDecoderException
*/
public function decode(mixed $input): ColorInterface
{
if (preg_match(self::PATTERN, $input, $matches) !== 1) {
throw new InvalidArgumentException('Invalid rgb() color syntax "' . $input . '"');
}
// 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);View on GitHub (pinned to 5598b9e397)
Solutions
- Use the accepted syntax: 'rgb(255 0 0)', 'rgb(255, 0, 0)', 'rgba(255 0 0 / 0.5)' or 'rgb(100% 0% 0%)'
- Normalize user input before parsing (e.g. strip extra whitespace, convert decimals to integers)
- Catch InvalidArgumentException and show a validation message when accepting free-form color strings
Example fix
// before
$color = \Intervention\Image\Colors\Rgb\Color::parse('rgb(25.5, 0, 0)');
// after
$color = \Intervention\Image\Colors\Rgb\Color::parse('rgb(26, 0, 0)'); // integer channels only Defensive patterns
Strategy: validation
Validate before calling
$pattern = '/^s?rgba?\s*\(\s*\d{1,3}(?:%|\s|,)' // quick pre-check
. '/i';
if (!preg_match('/^s?rgba? ?\(/i', $input)) {
throw new \RuntimeException('Not an rgb() string');
}
// full parity check with the library pattern is strictest; simplest: try parse and catch Type guard
function isRgbString(mixed $input): bool
{
return is_string($input) && preg_match(
'/^s?rgba? ?\( ?\d{1,3}[, ] ?\d{1,3}[, ] ?\d{1,3}'
. '(?: ?\/ ?|[, ] ?(?:0\.\d+|1\.0|\.\d+|\d{1,3}%|1|0))? ?\)$/i',
$input
) === 1;
} Try / catch
try {
$color = \Intervention\Image\Colors\Rgb\Color::parse('rgb(' . implode(' ', [$r, $g, $b]) . ')');
} catch (\Intervention\Image\Exceptions\InvalidArgumentException $e) {
$color = \Intervention\Image\Colors\Rgb\Color::create($r, $g, $b); // build directly from ints
} Prevention
- Emit canonical syntax: 'rgb(255 0 0)' or 'rgba(255 0 0 / 0.5)' with consistent separators
- Channels must be 1-3 digit integers or percentages; no decimals in r/g/b
- When you already have numeric channels, skip parsing and call Color::create($r, $g, $b)
When it happens
Trigger: Rgb\Color::parse('rgb(255;0;0)'), parse('rgb(255, 0)'), parse('rgb(3000 0 0)'), parse('rgba(255 0 0 / 2)'), or mixing separators ('rgb(255, 0 0)'); also decimals in r/g/b like 'rgb(25.5 0 0)'.
Common situations: Passing CSS strings authored for browsers with syntax the pattern rejects (decimal channels, slash separators with unusual spacing, mixed comma/space separators); user input from color pickers that emit modern CSS color syntax; missing one of the three channels.
Related errors
- Hex color has an invalid format
- Unable to parse RGB color from input "{input}"
- Invalid cmyk() color syntax "{input}"
- Unable to parse HSL color from input "{input}"
- Failed to import color {colorClass} to {class}
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/1b05140523b396ff.
Report an issue: GitHub.