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

  1. Clamp channels to 0-255 and alpha to 0.0-1.0 before formatting the color string
  2. Inspect ->getPrevious() of the ColorDecoderException to see exactly which value the Color constructor rejected
  3. 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

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

Related errors


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