{"record":{"id":"d3e099d4ced8f38f","repo":"Intervention/image","slug":"failed-to-apply-intervention-image-drivers-imagick-d3e099","errorCode":null,"errorMessage":"Failed to apply Intervention\\Image\\Drivers\\Imagick\\Modifiers\\DrawPolygonModifier, unable to build ImagickDraw object","messagePattern":"Failed to apply Intervention\\\\Image\\\\Drivers\\\\Imagick\\\\Modifiers\\\\DrawPolygonModifier, unable to build ImagickDraw object","errorType":"exception","errorClass":"ModifierException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php","lineNumber":62,"sourceCode":"     *\n     * @throws ModifierException\n     */\n    private function polygon(ImagickPixel $backgroundColor, ImagickPixel $borderColor): ImagickDraw\n    {\n        try {\n            $polygon = new ImagickDraw();\n            $polygon->setFillColor($backgroundColor);\n\n            if ($this->drawable->hasBorder()) {\n                $polygon->setStrokeColor($borderColor);\n                $polygon->setStrokeWidth($this->drawable->borderSize());\n            }\n\n            $polygon->polygon($this->points());\n\n            return $polygon;\n        } catch (ImagickException | ImagickDrawException $e) {\n            throw new ModifierException(\n                'Failed to apply ' . self::class . ', unable to build ImagickDraw object',\n                previous: $e,\n            );\n        }\n    }\n\n    /**\n     * Return points of drawable in processable form for ImagickDraw.\n     *\n     * @return array<array<string, int>>\n     */\n    private function points(): array\n    {\n        $points = [];\n        foreach ($this->drawable as $point) {\n            $points[] = ['x' => $point->x(), 'y' => $point->y()];\n        }\n","sourceCodeStart":44,"sourceCodeEnd":80,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Modifiers/DrawPolygonModifier.php#L44-L80","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n$points = [[acos(2) * 100, $y], [$x2, $y2], [$x3, $y3]]; // acos(2) = NAN leaks in\n$image->drawPolygon($points, fn($draw) => $draw->background('ff0'));\n\n// after\n$safe = array_map(\n    fn(array $p): array => [\n        'x' => (int) max(0, min($image->width() - 1, (int) $p['x'])),\n        'y' => (int) max(0, min($image->height() - 1, (int) $p['y'])),\n    ],\n    $points,\n);\n$image->drawPolygon($safe, fn($draw) => $draw->background('ff0'));","handlingStrategy":"try-catch","validationCode":"$points = array_map(\n    fn(array $p): array => [\n        'x' => (int) $p['x'],\n        'y' => (int) $p['y'],\n    ],\n    $points,\n);\n$invalid = array_filter($points, fn($p) =>\n    !is_finite($p['x']) || !is_finite($p['y'])\n);\nif (count($invalid) > 0 || count($points) < 3) {\n    throw new \\InvalidArgumentException('Polygon needs >= 3 finite integer points');\n}","typeGuard":"/** @param array<int,array{x:int,y:int}> $points */\nfunction isValidPolygonPoints(array $points, int $width, int $height): bool\n{\n    if (count($points) < 3) {\n        return false;\n    }\n    foreach ($points as $p) {\n        if (!isset($p['x'], $p['y']) || !is_int($p['x']) || !is_int($p['y'])) {\n            return false;\n        }\n        if ($p['x'] < -$width || $p['x'] > 2 * $width || $p['y'] < -$height || $p['y'] > 2 * $height) {\n            return false;\n        }\n    }\n    return true;\n}","tryCatchPattern":"use Intervention\\Image\\Exceptions\\ModifierException;\n\ntry {\n    $image->drawPolygon($points, $callback);\n} catch (ModifierException $e) {\n    $native = $e->getPrevious();\n    Log::warning('Polygon draw failed: ' . ($native?->getMessage() ?? $e->getMessage()));\n    throw $e;\n}","preventionTips":["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"],"tags":["intervention-image","imagick","imagickdraw","polygon","drawing","php"],"backgroundTag":"imagick-draw-object-failed","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}