Intervention/image · error · ModifierException

Failed to apply…

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.

Solutions

  1. Inspect the chained previous exception (catch ModifierException, log $e->getPrevious()) to see the exact native Imagick error
  2. Sanitize all polygon points: cast coordinates to int, reject NAN/INF, and keep values within the image dimensions
  3. Ensure any border width set in the draw callback is a non-negative number
  4. Increase PHP memory_limit and check ImageMagick resource limits if drawing on large images
  5. Review /etc/ImageMagick-*/policy.xml for memory and width/height caps if the previous exception mentions policy or resources
  6. 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

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


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

Appendix: 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)