Intervention/image · error · ModifierException
Failed to apply Intervention\Image\Drivers\Imagick\Modifiers
Error message
Failed to apply Intervention\Image\Drivers\Imagick\Modifiers\DrawPolygonModifier, unable to build ImagickDraw object
What it means
This ModifierException is thrown by the Imagick driver when drawing a polygon with $image->drawPolygon() and the native ImagickDraw object cannot be built. The private polygon() method in src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php:47 wraps ImagickException and ImagickDrawException raised by setFillColor(), setStrokeColor(), setStrokeWidth() or ImagickDraw::polygon() while converting your drawable into an ImagickDraw. The original native failure is chained as the previous exception, so inspect getPrevious() for the real cause.
Source
Thrown at src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php:62
*
* @throws ModifierException
*/
private function polygon(ImagickPixel $backgroundColor, ImagickPixel $borderColor): ImagickDraw
{
try {
$polygon = new ImagickDraw();
$polygon->setFillColor($backgroundColor);
if ($this->drawable->hasBorder()) {
$polygon->setStrokeColor($borderColor);
$polygon->setStrokeWidth($this->drawable->borderSize());
}
$polygon->polygon($this->points());
return $polygon;
} catch (ImagickException | ImagickDrawException $e) {
throw new ModifierException(
'Failed to apply ' . self::class . ', unable to build ImagickDraw object',
previous: $e,
);
}
}
/**
* Return points of drawable in processable form for ImagickDraw.
*
* @return array<array<string, int>>
*/
private function points(): array
{
$points = [];
foreach ($this->drawable as $point) {
$points[] = ['x' => $point->x(), 'y' => $point->y()];
}
View on GitHub (pinned to 5598b9e397)
Solutions
- Inspect the chained previous exception (catch ModifierException, log $e->getPrevious()) to see the exact native Imagick error
- Sanitize all polygon points: cast coordinates to int, reject NAN/INF, and keep values within the image dimensions
- Ensure any border width set in the draw callback is a non-negative number
- Increase PHP memory_limit and check ImageMagick resource limits if drawing on large images
- Review /etc/ImageMagick-*/policy.xml for memory and width/height caps if the previous exception mentions policy or resources
- Try the GD driver (ImageManager::withDriver(Driver::class)) to isolate an ImageMagick-specific problem
Example fix
// before
$points = [[acos(2) * 100, $y], [$x2, $y2], [$x3, $y3]]; // acos(2) = NAN leaks in
$image->drawPolygon($points, fn($draw) => $draw->background('ff0'));
// after
$safe = array_map(
fn(array $p): array => [
'x' => (int) max(0, min($image->width() - 1, (int) $p['x'])),
'y' => (int) max(0, min($image->height() - 1, (int) $p['y'])),
],
$points,
);
$image->drawPolygon($safe, fn($draw) => $draw->background('ff0')); Defensive patterns
Strategy: try-catch
Validate before calling
$points = array_map(
fn(array $p): array => [
'x' => (int) $p['x'],
'y' => (int) $p['y'],
],
$points,
);
$invalid = array_filter($points, fn($p) =>
!is_finite($p['x']) || !is_finite($p['y'])
);
if (count($invalid) > 0 || count($points) < 3) {
throw new \InvalidArgumentException('Polygon needs >= 3 finite integer points');
} Type guard
/** @param array<int,array{x:int,y:int}> $points */
function isValidPolygonPoints(array $points, int $width, int $height): bool
{
if (count($points) < 3) {
return false;
}
foreach ($points as $p) {
if (!isset($p['x'], $p['y']) || !is_int($p['x']) || !is_int($p['y'])) {
return false;
}
if ($p['x'] < -$width || $p['x'] > 2 * $width || $p['y'] < -$height || $p['y'] > 2 * $height) {
return false;
}
}
return true;
} Try / catch
use Intervention\Image\Exceptions\ModifierException;
try {
$image->drawPolygon($points, $callback);
} catch (ModifierException $e) {
$native = $e->getPrevious();
Log::warning('Polygon draw failed: ' . ($native?->getMessage() ?? $e->getMessage()));
throw $e;
} Prevention
- Cast and range-check every polygon coordinate to finite ints before drawing
- Reject polygons with fewer than 3 points at the application boundary
- Keep border sizes non-negative
- Log the chained previous exception — it contains the real ImageMagick error
When it happens
Trigger: Calling $image->drawPolygon($points, $callback) where a point coordinate is NAN, INF, a non-numeric value, or an integer that overflows ImageMagick's internal limits; setting a border_size that is negative or non-finite via the draw callback; passing a background/border color string that decodes to an invalid ImagickPixel; memory exhaustion while instantiating ImagickDraw.
Common situations: Polygon vertices computed from unvalidated user input or floating-point math (NaN from 0/0 divisions); drawing polygons on very large canvases under a low PHP memory_limit; shared-hosting ImageMagick installations with restrictive policy.xml settings; ImageMagick/imagick extension version mismatches after a server upgrade.
Related errors
- Failed to apply Intervention\Image\Drivers\Imagick\Modifiers
- Failed to apply Intervention\Image\Drivers\Imagick\Modifiers
- Color channel {class} value must be in range {min} to {max}
- Failed to apply Intervention\Image\Drivers\Imagick\Modifiers
- Failed to apply Intervention\Image\Drivers\Imagick\Modifiers
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/d3e099d4ced8f38f.
Report an issue: GitHub.