{"record":{"id":"d21334a4a2d93a16","repo":"Intervention/image","slug":"failed-to-apply-class-unable-to-modulate-image","errorCode":null,"errorMessage":"Failed to apply {class}, unable to modulate image","messagePattern":"Failed to apply (.+?), unable to modulate image","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\ModifierException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Modifiers/GrayscaleModifier.php","lineNumber":24,"sourceCode":"\nuse ImagickException;\nuse Intervention\\Image\\Exceptions\\ModifierException;\nuse Intervention\\Image\\Interfaces\\ImageInterface;\nuse Intervention\\Image\\Interfaces\\SpecializedInterface;\nuse Intervention\\Image\\Modifiers\\GrayscaleModifier as GenericGrayscaleModifier;\n\nclass GrayscaleModifier extends GenericGrayscaleModifier implements SpecializedInterface\n{\n    /**\n     * @throws ModifierException\n     */\n    public function apply(ImageInterface $image): ImageInterface\n    {\n        foreach ($image as $frame) {\n            try {\n                $result = $frame->native()->modulateImage(100, 0, 100);\n                if ($result === false) {\n                    throw new ModifierException(\n                        'Failed to apply ' . self::class . ', unable to modulate image',\n                    );\n                }\n            } catch (ImagickException $e) {\n                throw new ModifierException(\n                    'Failed to apply ' . self::class . ', unable to modulate image',\n                    previous: $e,\n                );\n            }\n        }\n\n        return $image;\n    }\n}\n","sourceCodeStart":6,"sourceCodeEnd":39,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Modifiers/GrayscaleModifier.php#L6-L39","documentation":"This ModifierException is thrown by $image->grayscale() when the native color-desaturation call reports failure by returning false. The Imagick driver desaturates via modulateImage(100, 0, 100) on every frame; a false return is converted to 'unable to modulate image' with no chained previous exception, meaning ImageMagick declined or failed the modulation in this environment.","triggerScenarios":"Calling $image->grayscale() on very large images whose frames exceed ImageMagick's configured resource limits; desaturating frames with corrupted pixel caches; environments whose policy.xml restricts channel modulation operations.","commonSituations":"Batch grayscale conversion of high-resolution uploads on memory-limited hosts; processing truncated files that decode but cannot be modulated; Docker/minimal ImageMagick builds; policy-restricted shared hosting.","solutions":["Retry on a downscaled copy to confirm resource limits as the cause","Check and raise ImageMagick resource limits in policy.xml (`magick -list resource` to inspect)","Increase PHP memory_limit for large frames","Re-encode suspicious sources before processing","Update ImageMagick and the imagick extension to current versions"],"exampleFix":"// before\nforeach ($uploads as $path) {\n    $manager->read($path)->grayscale(); // fails on 80MP images\n}\n\n// after\nforeach ($uploads as $path) {\n    $image = $manager->read($path);\n    if ($image->width() * $image->height() > 40_000_000) {\n        $image->scaleDown(width: 5000);\n    }\n    $image->grayscale();\n}","handlingStrategy":"try-catch","validationCode":"$pixelCount = $image->width() * $image->height();\nif ($pixelCount > 40_000_000) {\n    $image->scaleDown(width: 5000);\n}\n$image->grayscale();","typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\ModifierException;\n\ntry {\n    $image->grayscale();\n} catch (ModifierException $e) {\n    Log::warning('Grayscale failed: ' . optional($e->getPrevious())->getMessage());\n    throw $e;\n}","preventionTips":["Downscale oversized images before desaturation on limited hosts","Audit policy.xml when grayscale fails only for large files","Re-encode untrusted uploads before batch conversion","No chained exception in this variant — suspect environment limits first"],"tags":["intervention-image","imagick","grayscale","modulate","resource-limits","php"],"backgroundTag":"imagick-color-modulation-failed","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}