Intervention/image · info · ColorDecoderException

Failed to decode hex color

Error message

Failed to decode hex color

What it means

While converting hex chunks to decimals, HexColorDecoder::decode() throws ColorDecoderException if any chunk is neither 1 nor 2 characters long. Because chunks come from str_split() of a 3/4-digit (1-char chunks) or 6/8-digit (2-char chunks) string, this branch is a defensive guard that cannot be reached through the built-in pattern; it would require a subclass overriding PATTERN plus the length match to produce odd chunk sizes.

Source

Thrown at src/Colors/Rgb/Decoders/HexColorDecoder.php:68

    public function decode(mixed $input): ColorInterface
    {
        if (preg_match(static::PATTERN, $input, $matches) !== 1) {
            throw new InvalidArgumentException('Hex color has an invalid format');
        }

        // split into hex chunks
        $values = match (strlen($matches['hex'])) {
            3, 4 => str_split($matches['hex']),
            6, 8 => str_split($matches['hex'], 2),
            default => throw new InvalidArgumentException('Hex color has an incorrect length'),
        };

        // convert to decimal
        $values = array_map(function (string $value): int {
            return match (strlen($value)) {
                1 => (int) hexdec($value . $value),
                2 => (int) hexdec($value),
                default => throw new ColorDecoderException('Failed to decode hex color'),
            };
        }, $values);

        // normalize
        $values = count($values) === 3 ? array_pad($values, 4, 255) : $values;
        $values = array_map(fn(int $value): float => $value / 255, $values);

        return Rgb::colorFromNormalized($values);
    }
}

View on GitHub (pinned to 5598b9e397)

Solutions

  1. No user action required for stock usage
  2. If you maintain a decoder subclass, keep chunk sizes at 1 or 2 characters
  3. Treat occurrences as a signal that local decoder overrides diverged from upstream
Defensive patterns

Strategy: try-catch

Try / catch

try {
    $color = $decoder->decode($hex);
} catch (\Intervention\Image\Exceptions\ColorDecoderException $e) {
    // defensive branch; if hit, your decoder overrides produce malformed chunks
    $color = \Intervention\Image\Colors\Rgb\Color::create(0, 0, 0);
}

Prevention

When it happens

Trigger: Practically unreachable via public APIs; only a heavily customized HexColorDecoder subclass that changes both PATTERN and the length match could produce malformed chunks.

Common situations: Deep forks of the decoder pipeline; none in normal usage.

Understand the failure class

Related errors


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