{"record":{"id":"32d96c1325565a47","repo":"Intervention/image","slug":"failed-to-get-frame-delay","errorCode":null,"errorMessage":"Failed to get frame delay","messagePattern":"Failed to get frame delay","errorType":"exception","errorClass":"DriverException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Frame.php","lineNumber":111,"sourceCode":"            );\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    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see DriverInterface::setDelay()\n     *\n     * @throws DriverException\n     */\n    public function setDelay(float $delay): FrameInterface\n    {\n        try {\n            $this->native->setImageDelay(intval(round($delay * 100)));\n        } catch (ImagickException $e) {\n            throw new DriverException('Failed to set frame disposal method', previous: $e);\n        }\n","sourceCodeStart":93,"sourceCodeEnd":129,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Frame.php#L93-L129","documentation":"Frame::delay() reads the per-frame animation delay as getImageDelay() / 100 (src/Drivers/Imagick/Frame.php:109) — seconds from ImageMagick's 1/100s ticks — and wraps any ImagickException as DriverException. It fails when the frame's native Imagick is no longer usable (cleared/destroyed or corrupted), typically while iterating frames of an animated GIF/WebP.","triggerScenarios":"Iterating $image->frames() of an animated GIF/WebP and calling delay() after manual clear()/destroy() of the native; operating on a partially decoded or corrupted animation whose frame native is invalid.","commonSituations":"Custom animation processing that frees resources mid-loop; corrupted uploads that decode only partially; modifiers holding stale frame references after an earlier exception was swallowed.","solutions":["Inspect $e->getPrevious()->getMessage() for the underlying ImageMagick error","Never clear()/destroy() frame natives while the Frame object is still in use","Re-read the animation from its source when errors occurred earlier in the pipeline","Fail fast: stop frame iteration on the first wrapped error"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"use Intervention\\Image\\Exceptions\\DriverException;\n\ntry {\n    $delay = $frame->delay();\n} catch (DriverException $e) {\n    // native frame is unusable; re-read the animation instead of guessing\n    error_log('Frame delay failed: ' . $e->getPrevious()?->getMessage());\n    throw $e;\n}","preventionTips":["Do all frame reads (delay, size, offset) before any manual teardown of natives","Re-read animated sources from disk rather than reusing frames after errors","Validate animation uploads with a full decode before storing them"],"tags":["imagick","frame","animation","delay","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"}