{"record":{"id":"57b03de504591b06","repo":"Intervention/image","slug":"failed-to-get-frame-disposal-method","errorCode":null,"errorMessage":"Failed to get frame disposal method","messagePattern":"Failed to get frame disposal method","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Frame.php","lineNumber":145,"sourceCode":"            throw new DriverException('Failed to set frame disposal method', previous: $e);\n        }\n\n        return $this;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DriverInterface::disposalMethod()\n     *\n     * @throws DriverException\n     */\n    public function disposalMethod(): int\n    {\n        try {\n            return $this->native->getImageDispose();\n        } catch (ImagickException $e) {\n            throw new DriverException('Failed to get frame disposal method', previous: $e);\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DriverInterface::setDisposalMethod()\n     *\n     * @throws InvalidArgumentException\n     * @throws DriverException\n     */\n    public function setDisposalMethod(int $method): FrameInterface\n    {\n        if (!in_array($method, [0, 1, 2, 3])) {\n            throw new InvalidArgumentException('Value for argument disposal method \"$method\" must be 0, 1, 2 or 3');\n        }\n\n        try {","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Frame.php#L127-L163","documentation":"Thrown by Frame::disposalMethod() in the Imagick driver when the underlying ext-imagick call Imagick::getImageDispose() raises an ImagickException. The disposal method describes how an animated frame (GIF/APNG/WebP) is cleared before the next frame is drawn. The library wraps the raw native failure in a DriverException so callers only deal with Intervention exception types.","triggerScenarios":"Calling $image->frames() iteration APIs or any code path that reads frame metadata (e.g. animating/inspecting GIFs) after the Imagick object is corrupted or its underlying ImageMagick wand was destroyed/cleared. Also happens when the loaded image has no frame in the current iteration position, or when the ext-imagick extension is mismatched with the installed ImageMagick system library.","commonSituations":"Reusing a frame object after free/destroy on the native handle; processing GIFs in long-running workers where memory corruption or resource exhaustion (ImageMagick resource limits) invalidates wands; imagick extension compiled against a different ImageMagick major version than the one loaded at runtime; multi-threaded/parallel access to the same Imagick object (php-parallel, Swoole coroutines).","solutions":["Inspect the previous exception via $e->getPrevious() to get the real ImagickException message (e.g. 'unable to read image' or resource-limit errors) and address that root cause.","If the message points to resource limits, raise limits in policy.xml (memory, area, disk) or via Imagick::setResourceLimit().","Reload the image from its source and rebuild frames instead of reusing stale Frame objects; do not cache Frame instances across requests or after modifying the native handle.","Verify ext-imagick and ImageMagick versions match (php -i | grep -i imagick vs convert -version); rebuild/reinstall the extension if they diverge."],"exampleFix":"// before (stale frame reused after heavy native operations)\n$frame = $image->frames()->first();\n$frame->native()->destroy();\n$method = $frame->disposalMethod(); // DriverException\n\n// after\n$method = $image->frames()->first()->disposalMethod();","handlingStrategy":"try-catch","validationCode":"// cheap liveness probe before reading frame metadata\nif ($frame->native()->count() < 1 || $frame->size()->width() < 1) {\n    throw new RuntimeException('frame is not readable');\n}","typeGuard":"function isReadableFrame(\\Intervention\\Image\\Drivers\\Imagick\\Frame $frame): bool\n{\n    try {\n        return $frame->size()->width() > 0 && $frame->native()->count() > 0;\n    } catch (\\Throwable) {\n        return false;\n    }\n}","tryCatchPattern":"use Intervention\\Image\\Exceptions\\DriverException;\ntry {\n    $method = $frame->disposalMethod();\n} catch (DriverException $e) {\n    $native = $e->getPrevious()?->getMessage() ?? 'unknown';\n    // recover: reload image, skip frame, or surface $native in logs\n}","preventionTips":["Never reuse Frame objects after touching $frame->native() with destroy()/clear().","Re-decode images at the start of each pipeline stage instead of caching frames across failures.","Keep ext-imagick and the system ImageMagick on matching versions."],"tags":["imagick","animation","gif","frame-metadata","driver-exception"],"backgroundTag":"imagick-driver-exception","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}