Intervention/image · error · Intervention\Image\Exceptions\ColorException

Failed to import color {color_class} to {colorspace_class}

Error message

Failed to import color {color_class} to {colorspace_class}

What it means

Hsv\Colorspace::importRgbColor() has a special grayscale branch (chroma === 0.0) that constructs Hsv\Color(0, 0, value, alpha). If that constructor throws an InvalidArgumentException (a channel out of bounds), it is wrapped in this ColorException with the original attached as previous. For valid RgbColor inputs the computed value stays in 0-100, so failures trace back to an out-of-range alpha or corrupted numeric input.

Source

Thrown at src/Colors/Hsv/Colorspace.php:121

        );

        // take only RGB
        $values = array_slice($values, 0, 3);

        // calculate chroma
        $min = min(...$values);
        $max = max(...$values);
        $chroma = $max - $min;

        // calculate value
        $v = 100 * $max;

        if ($chroma === 0.0) {
            // grayscale color
            try {
                return new Color(0, 0, intval(round($v)), $color->alpha()->normalized());
            } catch (InvalidArgumentException $e) {
                throw new ColorException(
                    'Failed to import color ' . $color::class . ' to ' . $this::class,
                    previous: $e,
                );
            }
        }

        // calculate saturation
        $s = 100 * ($chroma / $max);

        // calculate hue
        [$r, $g, $b] = $values;
        $h = match (true) {
            ($r === $min) => 3 - (($g - $b) / $chroma),
            ($b === $min) => 1 - (($r - $g) / $chroma),
            default => 5 - (($b - $r) / $chroma),
        } * 60;

        try {

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Inspect $e->getPrevious() for the failing channel and bound
  2. Fix the source alpha to return a normalized 0.0-1.0 float
  3. Rebuild the source RgbColor via its validating constructor before converting
  4. Wrap conversions of untrusted colors in try/catch and use a safe fallback such as Hsv\Color::create(0, 0, 0)

Example fix

// before
$rgb = new RgbColor(128, 128, 128, 128); // alpha accidentally on 0-255 scale

// after
$rgb = new RgbColor(128, 128, 128, 1.0); // alpha normalized 0.0-1.0
Defensive patterns

Strategy: try-catch

Validate before calling

$alpha = $rgbColor->alpha()->normalized();
if (!is_finite($alpha) || $alpha < 0.0 || $alpha > 1.0) {
    // rebuild with clamped alpha before converting
    $rgbColor = Rgb\Color::create(
        $rgbColor->red()->value(),
        $rgbColor->green()->value(),
        $rgbColor->blue()->value(),
        min(1.0, max(0.0, is_finite($alpha) ? $alpha : 1.0)),
    );
}

Try / catch

use Intervention\Image\Exceptions\ColorException;

try {
    $hsv = $rgbColor->toColorspace(Hsv\Colorspace::class);
} catch (ColorException $e) {
    $hsv = Hsv\Color::create(0, 0, 0); // safe fallback
}

Prevention

When it happens

Trigger: $rgbColor->toColorspace(Hsv\Colorspace::class) on a grayscale RGB color (r === g === b) where the source color's alpha()->normalized() is outside 0.0-1.0, or NaN channel values produce an invalid intval/round result.

Common situations: Custom color implementations returning unnormalized alpha (e.g. 0-100 or 0-255 scale); colors reconstructed from stored raw values without validation; numeric corruption from external pixel pipelines.

Related errors


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