{"record":{"id":"49fef71d5a7a393a","repo":"Intervention/image","slug":"target-size-needs-width-and-height","errorCode":null,"errorMessage":"Target size needs width and height","messagePattern":"Target size needs width and height","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\StateException","httpStatus":null,"severity":"error","filePath":"src/Geometry/Tools/Resizer.php","lineNumber":85,"sourceCode":"    }\n\n    /**\n     * Return target width of resizer if available.\n     */\n    protected function targetHeight(): ?int\n    {\n        return $this->hasTargetHeight() ? $this->height : null;\n    }\n\n    /**\n     * Return target size object.\n     *\n     * @throws StateException\n     */\n    protected function targetSize(): SizeInterface\n    {\n        if (!$this->hasTargetWidth() || !$this->hasTargetHeight()) {\n            throw new StateException('Target size needs width and height');\n        }\n\n        try {\n            return new Size($this->width, $this->height);\n        } catch (InvalidArgumentException $e) {\n            throw new StateException('Invalid target size', previous: $e);\n        }\n    }\n\n    /**\n     * Set target width of resizer.\n     */\n    public function toWidth(int $width): self\n    {\n        $this->width = $width;\n\n        return $this;\n    }","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Geometry/Tools/Resizer.php#L67-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Set both dimensions: Resizer::to(300, 200), or ->toWidth(300)->toHeight(200), or ->toSize(new Size(300, 200))","If you want aspect-preserving auto-calculation of the second dimension, use scale()/resize() on the image instead of cover/contain","If dimensions come from configuration, validate that both keys are present before building the resizer"],"exampleFix":"// before\n$resizer = Resizer::to(300); // height never set\n$resizer->cover($size); // StateException\n\n// after\n$resizer = Resizer::to(300, 200);\n$resizer->cover($size);","handlingStrategy":"validation","validationCode":"$resizer = Resizer::to($targetWidth, $targetHeight);\nif ($targetWidth === null || $targetHeight === null) {\n    throw new InvalidArgumentException('cover/contain require both width and height');\n}","typeGuard":"function hasFullTargetBox(Resizer $r): bool\n{\n    $r = (fn () => ['w' => $this->width, 'h' => $this->height])->call($r);\n    return $r['w'] !== null && $r['h'] !== null;\n}","tryCatchPattern":"try {\n    $resizer->cover($size);\n} catch (StateException $e) {\n    // incomplete resizer: set the missing dimension and retry\n}","preventionTips":["Always construct the full target box with Resizer::to($w, $h) in one call","Use scale()/resize() when only one dimension is known","Assert both config keys exist before building cover/contain operations"],"tags":["geometry","resizer","state","dimensions"],"backgroundTag":"missing-required-argument","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}