{"record":{"id":"b9c18917ef739ed5","repo":"Intervention/image","slug":"failed-to-get-frame-size","errorCode":null,"errorMessage":"Failed to get frame size","messagePattern":"Failed to get frame size","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Frame.php","lineNumber":95,"sourceCode":"        return $this->native;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DriverInterface::size()\n     *\n     * @throws DriverException\n     */\n    public function size(): SizeInterface\n    {\n        try {\n            return new Size(\n                $this->native->getImageWidth(),\n                $this->native->getImageHeight(),\n            );\n        } catch (ImagickException | InvalidArgumentException $e) {\n            throw new DriverException('Failed to get frame size', previous: $e);\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DriverInterface::delay()\n     *\n     * @throws DriverException\n     */\n    public function delay(): float\n    {\n        try {\n            return $this->native->getImageDelay() / 100;\n        } catch (ImagickException $e) {\n            throw new DriverException('Failed to get frame delay', previous: $e);\n        }\n    }","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Frame.php#L77-L113","documentation":"Frame::size() wraps getImageWidth()/getImageHeight() (src/Drivers/Imagick/Frame.php:90-93) and re-throws any ImagickException as DriverException. These getters only fail when the underlying Imagick object is in an invalid state — typically cleared/destroyed, or holding a failed decode — so the actionable detail is in the previous exception.","triggerScenarios":"Calling size() (or modifiers such as resize/crop that query frame size) after the native Imagick was clear()ed/destroyed; using a Frame whose native came from an aborted decode; double-processing an already-freed core.","commonSituations":"Custom modifiers that call $imagick->clear() and then let the library continue; caching Frame/Core objects beyond their lifetime; swallowing an earlier exception and continuing the pipeline on a broken core.","solutions":["Inspect $e->getPrevious()->getMessage() for the native ImageMagick error","Do not clear()/destroy a native you hand back to the library; clone before manual teardown","Re-read the image from the original source when pipeline state is uncertain","Abort the whole operation instead of continuing after a caught Imagick error"],"exampleFix":"// before\n$imagick->clear();\n$size = $frame->size(); // native already freed\n\n// after\n$size = $frame->size();\n$imagick->clear();","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\DriverException;\n\ntry {\n    $size = $frame->size();\n} catch (DriverException $e) {\n    $reason = $e->getPrevious()?->getMessage() ?? $e->getMessage();\n    if (str_contains(strtolower($reason), 'no image loaded') || str_contains($reason, 'destroyed')) {\n        // core was cleared: recover by re-reading the source\n        $image = $manager->read($sourcePath);\n        $size = $image->frames()->first()->size();\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Never call clear()/destroy() on natives still owned by the library; clone first","Treat any caught Imagick error as fatal for that image; do not continue the pipeline","Keep frame references only within the modifier that produced them"],"tags":["imagick","frame","invalid-state","use-after-free"],"backgroundTag":"use-after-free","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}