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

  1. Use the accepted syntax: 'rgb(255 0 0)', 'rgb(255, 0, 0)', 'rgba(255 0 0 / 0.5)' or 'rgb(100% 0% 0%)'
  2. Normalize user input before parsing (e.g. strip extra whitespace, convert decimals to integers)
  3. 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

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


AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23). Data as JSON: /api/errors/1b05140523b396ff. Report an issue: GitHub.