{"record":{"id":"eaa9d4185f14ff80","repo":"Intervention/image","slug":"quality-must-be-in-range-0-to-100-eaa9d4","errorCode":null,"errorMessage":"Quality must be in range 0 to 100","messagePattern":"Quality must be in range 0 to 100","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Encoders/JpegEncoder.php","lineNumber":24,"sourceCode":"\nuse Intervention\\Image\\Drivers\\SpecializableEncoder;\nuse Intervention\\Image\\Exceptions\\InvalidArgumentException;\n\nclass JpegEncoder extends SpecializableEncoder\n{\n    /**\n     * Create new encoder object.\n     *\n     * @param null|bool $strip Strip EXIF metadata\n     * @throws InvalidArgumentException\n     */\n    public function __construct(\n        public int $quality = self::DEFAULT_QUALITY,\n        public bool $progressive = false,\n        public ?bool $strip = null,\n    ) {\n        if ($quality < 0 || $quality > 100) {\n            throw new InvalidArgumentException('Quality must be in range 0 to 100');\n        }\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":28,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Encoders/JpegEncoder.php#L6-L28","documentation":"JpegEncoder (base class for the driver-specific JPEG encoders) validates $quality in its constructor and throws InvalidArgumentException for any integer below 0 or above 100. Quality reaches it directly via new JpegEncoder(quality: N) or through forwarded options: $image->save('out.jpg', quality: N) resolves the encoder from the extension and constructs it with your options. Note that quality is the first positional parameter, so new JpegEncoder(120) triggers it too.","triggerScenarios":"new JpegEncoder(101), $image->save('thumb.jpg', quality: -5), or $image->encodeUsingPath('out.jpg', quality: $userInput) with out-of-range input. Also new JpegEncoder(120, true) when quality is passed positionally.","commonSituations":"User-facing compression sliders or API parameters forwarded without bounds checking; config drift after deploying a higher default; quality computed from image size or business logic that occasionally exceeds the limit.","solutions":["Clamp quality to 0-100 before passing: $q = max(0, min(100, $q))","Validate the parameter at the API/request boundary","Use the named argument (quality:) to avoid positional mix-ups with $progressive"],"exampleFix":"// before\n$image->save('out.jpg', quality: $request->input('quality'));\n\n// after\n$image->save('out.jpg', quality: max(0, min(100, (int) $request->input('quality', 75))));","handlingStrategy":"validation","validationCode":"$quality = max(0, min(100, (int) $quality));\n$image->save('out.jpg', quality: $quality);","typeGuard":"function isValidQuality(mixed $quality): bool\n{\n    return is_int($quality) && $quality >= 0 && $quality <= 100;\n}","tryCatchPattern":null,"preventionTips":["Never forward client-supplied quality parameters unvalidated","Use the named argument quality: to avoid positional confusion with progressive","Clamp once where the value enters the system, not at each encoder call"],"tags":["php","intervention-image","encoder","jpeg","quality","invalid-argument"],"backgroundTag":"parameter-out-of-range","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}