Intervention/image · error · Intervention\Image\Exceptions\StateException
Invalid target size
Error message
Invalid target size
What it means
targetSize() wraps the construction of a Size object from the resizer's stored width/height; if Size's constructor rejects the values (width or height < 0, see Size.php:36-46), it is rethrown as StateException('Invalid target size') with the original InvalidArgumentException attached as previous. The key subtlety: the Resizer constructor only validates values passed to it — the toWidth()/toHeight() setters (Resizer.php:98-113) assign without any validation, so negative values can slip in there and only explode later at cover/contain time.
Source
Thrown at src/Geometry/Tools/Resizer.php:91
{
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;
}
/**
* Set target height of resizer.
*/
public function toHeight(int $height): self
{View on GitHub (pinned to 5598b9e397)
Solutions
- Inspect getPrevious() to see which dimension and value Size rejected
- Validate before calling toWidth()/toHeight() — the setters do not validate: if ($w < 0) { throw ... } or clamp with max(0, $w)
- Audit arithmetic that computes target dimensions (padding/margin subtraction is a common source of negatives)
- Set dimensions through Resizer::to()/the constructor where possible, which validates immediately
Example fix
// before $resizer->toWidth($targetWidth - 2 * $padding)->toHeight($h); // negative when target < padding // after $resizer->toWidth(max(0, $targetWidth - 2 * $padding))->toHeight($h);
Defensive patterns
Strategy: validation
Validate before calling
$width = max(0, $targetWidth - 2 * $padding); $resizer = Resizer::to(300, 200)->toWidth($width); // setter does not validate — clamp first
Type guard
function isNonNegativeDimension(int $value): bool
{
return $value >= 0;
} Try / catch
try {
$resizer->cover($sourceSize);
} catch (StateException $e) {
$cause = $e->getPrevious(); // original InvalidArgumentException names the bad dimension
} Prevention
- Never trust toWidth()/toHeight() to validate — they assign blindly
- Clamp computed dimensions to >= 0 before setting them
- Prefer the constructor / Resizer::to() which validates immediately
When it happens
Trigger: $resizer->toWidth(-10)->toHeight(50)->cover(...) — setter-assigned negative dimension passes silently and fails in targetSize(); also toSize() with a custom SizeInterface implementation returning negative width()/height().
Common situations: Arithmetic that produces negative dimensions (e.g. subtracting padding from a small target size), sign errors, or custom SizeInterface implementations that are not validated. Distant, hard-to-trace failure because the invalid value was accepted earlier by a setter.
Related errors
- Target size needs width and height
- Height must be greater than or equal to 1
- Invalid image size
- Invalid image size. Must be int<1, max>
- Failed to apply Intervention\Image\Drivers\Gd\Modifiers\Draw
AI-assisted analysis of Intervention/image@5598b9e397 (2026-08-23).
Data as JSON: /api/errors/edbee575ba8a7d7d.
Report an issue: GitHub.