Intervention/image · error · InvalidArgumentException

Invalid image size

Error message

Invalid image size

What it means

Cloner::cloneEmpty() builds a fresh truecolor canvas of the requested Size (or the source GdImage's own dimensions when no Size is passed). Before calling imagecreatetruecolor() it rejects any target with width < 1 or height < 1, because GD cannot create a zero/negative canvas. The size can come either from the source image itself (imagesx/imagesy of a broken native) or from the caller-supplied $size argument.

Source

Thrown at src/Drivers/Gd/Cloner.php:52

     * Create an "empty" clone of the given GdImage
     *
     * This only retains the basic data without transferring the actual image.
     * It is optionally possible to change the size of the result and set a
     * background color.
     *
     * @throws InvalidArgumentException
     * @throws DriverException
     */
    public static function cloneEmpty(
        GdImage $gd,
        ?SizeInterface $size = null,
        Color $background = new Color(255, 255, 255, 0),
    ): GdImage {
        // define size
        $size = $size ?: new Size(imagesx($gd), imagesy($gd));

        if ($size->width() < 1 || $size->height() < 1) {
            throw new InvalidArgumentException('Invalid image size');
        }

        // create new gd image with same size or new given size
        $clone = imagecreatetruecolor($size->width(), $size->height());
        if ($clone === false) {
            throw new DriverException('Failed to create new image while cloning');
        }

        // copy resolution to clone
        $resolution = imageresolution($gd);
        if (is_array($resolution) && array_key_exists(0, $resolution) && array_key_exists(1, $resolution)) {
            imageresolution($clone, $resolution[0], $resolution[1]);
        }

        // fill with background
        $processor = new ColorProcessor();

        imagefill($clone, 0, 0, $processor->export($background));

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Clamp requested dimensions before calling image APIs: max(1, (int) round($width))
  2. Validate user input upstream: reject non-positive width/height at the request layer
  3. If it triggers without an explicit size, the source GdImage itself is broken — rebuild it via ImageManager::read()

Example fix

// before
$image->resize(0, 100);

// after
$width = max(1, (int) round($request->input('width')));
$image->resize($width, 100);
Defensive patterns

Strategy: validation

Validate before calling

$width = max(1, (int) round($width));
$height = max(1, (int) round($height));
if ($width < 1 || $height < 1) {
    throw new InvalidArgumentException('width/height must be >= 1');
}

Prevention

When it happens

Trigger: Passing a Size with a 0 or negative side directly: Cloner::cloneEmpty($gd, new Size(0, 100)); higher-level operations (resize/contain/cover paths, text-block sizing) that compute a target size rounding down to 0 for extreme aspect ratios; cloning a corrupted native whose imagesx() returns 0.

Common situations: User-supplied width/height not validated before resizing (resize(0, 100)); contain() into a container whose aspect ratio collapses one dimension; float dimensions floor()ed to 0.

Related errors


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