Intervention/image · error · Intervention\Image\Exceptions\ColorException
Unable to import color {colorClass} to {class}
Error message
Unable to import color {colorClass} to {class} What it means
When RemoveAnimationModifier's $position is a string, normalizePosition() first casts numeric strings to int, then tries the strict pattern ^[0-9]{1,3}%$ for percentages. Any other string — negative percents, 4+ digit percents, spaces, decimals, unit suffixes — throws InvalidArgumentException. The regex is deliberately tight: 1-3 digits followed immediately by '%'.
Source
Thrown at src/Colors/Cmyk/Colorspace.php:85
/**
* {@inheritdoc}
*
* @see ColorspaceInterface::importColor()
*
* @throws ColorException
*/
public function importColor(ColorInterface $color): CmykColor
{
return match ($color::class) {
OklchColor::class,
OklabColor::class,
HsvColor::class,
NamedColor::class,
HslColor::class => $this->importViaRgbColor($color),
RgbColor::class => $this->importRgbColor($color),
CmykColor::class => $color,
default => throw new ColorException(
'Unable to import color ' . $color::class . ' to ' . $this::class,
),
};
}
/**
* Import given RGB color to CMYK colorspace.
*
* @throws ColorException
*/
private function importRgbColor(RgbColor $color): CmykColor
{
$c = (255 - $color->red()->value()) / 255.0 * 100;
$m = (255 - $color->green()->value()) / 255.0 * 100;
$y = (255 - $color->blue()->value()) / 255.0 * 100;
$k = intval(round(min([$c, $m, $y])));
$c = intval(round($c - $k));View on GitHub (pinned to 5598b9e397)
Solutions
- Normalize input before calling: strip spaces, cast integer-like values to int, format percents as 'NN%' with 1-3 digits.
- Validate with the same pattern: preg_match('/^[0-9]{1,3}%$/', $value) === 1 before passing a string.
- Pass an int when you know the frame index; strings are only needed for percentage selection.
- For values above 999% (nonsensical) clamp or reject outright at your input layer.
Example fix
// before
$image->removeAnimation($request->input('position')); // '50 %' throws
// after
$position = preg_replace('/\s+/', '', $request->input('position'));
if (is_numeric($position)) {
$position = (int) $position;
}
$image->removeAnimation($position); Defensive patterns
Strategy: validation
Validate before calling
$position = preg_replace('/\s+/', '', (string) $position);
if (is_numeric($position)) {
$position = max(0, (int) $position);
} elseif (preg_match('/^[0-9]{1,3}%$/', $position) !== 1) {
throw new InvalidArgumentException('Bad position: ' . $position);
}
$image->removeAnimation($position); Type guard
function isRemovableAnimationPosition(int|string $position): bool
{
return is_int($position)
? $position >= 0
: (is_numeric($position) || preg_match('/^[0-9]{1,3}%$/', $position) === 1);
} Try / catch
try {
$image->removeAnimation($position);
} catch (Intervention\Image\Exceptions\InvalidArgumentException $e) {
// fall back to frame 0
$image->removeAnimation(0);
} Prevention
- Strip whitespace from user input before passing position strings.
- Only 1-3 digits followed by '%' are accepted — no minus sign, no decimals.
- Cast integer-like strings to int before calling.
When it happens
Trigger: ->removeAnimation('50 %') (space), ->removeAnimation('-10%'), ->removeAnimation('1000%'), ->removeAnimation('50percent'), ->removeAnimation('first').
Common situations: User input trimmed insufficiently ('50 ' or '50 %'); percentage values from spreadsheets formatted like '50.0%'; locale-specific formatting; attempts to use frame labels or relative keywords.
Related errors
- Percentage value must be between -100 and 100
- Normalized color value must be in range 0 to 1
- Failed to apply {class}, unable to re-apply image frame
- Failed to invert color
- Color channel {class} value must be in range {min} to {max}
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/a29f1526f311619d.
Report an issue: GitHub.