Intervention/image · error · Intervention\Image\Exceptions\StateException

Target size needs width and height

Error message

Target size needs width and height

What it means

The internal targetSize() method requires both a target width and a target height before it can build a Size object, and throws this StateException when either is still null. It is called by the Resizer's cover, contain and containDown operations, which by definition need a complete target box. The error tells you the resizer was built incompletely rather than with an invalid value.

Source

Thrown at src/Geometry/Tools/Resizer.php:85

    }

    /**
     * Return target width of resizer if available.
     */
    protected function targetHeight(): ?int
    {
        return $this->hasTargetHeight() ? $this->height : null;
    }

    /**
     * Return target size object.
     *
     * @throws StateException
     */
    protected function targetSize(): SizeInterface
    {
        if (!$this->hasTargetWidth() || !$this->hasTargetHeight()) {
            throw new StateException('Target size needs width and height');
        }

        try {
            return new Size($this->width, $this->height);
        } catch (InvalidArgumentException $e) {
            throw new StateException('Invalid target size', previous: $e);
        }
    }

    /**
     * Set target width of resizer.
     */
    public function toWidth(int $width): self
    {
        $this->width = $width;

        return $this;
    }

View on GitHub (pinned to 5598b9e397)

Solutions

  1. Set both dimensions: Resizer::to(300, 200), or ->toWidth(300)->toHeight(200), or ->toSize(new Size(300, 200))
  2. If you want aspect-preserving auto-calculation of the second dimension, use scale()/resize() on the image instead of cover/contain
  3. If dimensions come from configuration, validate that both keys are present before building the resizer

Example fix

// before
$resizer = Resizer::to(300); // height never set
$resizer->cover($size); // StateException

// after
$resizer = Resizer::to(300, 200);
$resizer->cover($size);
Defensive patterns

Strategy: validation

Validate before calling

$resizer = Resizer::to($targetWidth, $targetHeight);
if ($targetWidth === null || $targetHeight === null) {
    throw new InvalidArgumentException('cover/contain require both width and height');
}

Type guard

function hasFullTargetBox(Resizer $r): bool
{
    $r = (fn () => ['w' => $this->width, 'h' => $this->height])->call($r);
    return $r['w'] !== null && $r['h'] !== null;
}

Try / catch

try {
    $resizer->cover($size);
} catch (StateException $e) {
    // incomplete resizer: set the missing dimension and retry
}

Prevention

When it happens

Trigger: Resizer::to(300) followed by ->cover(...), ->contain(...) or ->containDown(...) with only one dimension set; or building via (new Resizer())->toWidth(300) and never calling toHeight()/toSize(). hasTargetWidth()/hasTargetHeight() (is_int checks) fail because the property is still null.

Common situations: Copy-pasting a resize chain where the second dimension was dropped, assuming the library will infer the missing dimension (cover/contain cannot — unlike scale/resize they need an explicit box), or branching code that sets height conditionally.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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