{"record":{"id":"10fbfe4acc7d1dcc","repo":"Intervention/image","slug":"last-frame-not-found-in-image","errorCode":null,"errorMessage":"Last frame not found in image","messagePattern":"Last frame not found in image","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\StateException","httpStatus":null,"severity":"error","filePath":"src/Drivers/Imagick/Core.php","lineNumber":412,"sourceCode":"        } catch (InvalidArgumentException $e) {\n            throw new StateException('First frame not found in image', previous: $e);\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see CollectableInterface::last()\n     *\n     * @throws DriverException\n     * @throws StateException\n     */\n    public function last(): FrameInterface\n    {\n        try {\n            return $this->frame($this->count() - 1);\n        } catch (InvalidArgumentException $e) {\n            throw new StateException('Last frame not found in image', previous: $e);\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see CoreInterface::meta()\n     */\n    public function meta(): CollectionInterface\n    {\n        return $this->meta;\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see CollectionInterface::toArray()\n     */","sourceCodeStart":394,"sourceCodeEnd":430,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Core.php#L394-L430","documentation":"Thrown by Core::last() when frame(count() - 1) cannot find the frame — wrapped as StateException. With an empty core, count() is 0 so it searches for frame(-1), which never matches; with a populated core it would only fail if the stack got corrupted between the count and the scan.","triggerScenarios":"Calling $image->core()->last() on a core with zero frames (after clear(), an all-removing slice(), or manual construction without add()), or on a stack whose frames were invalidated mid-operation.","commonSituations":"Same empty-core situations as first(); batch pipelines that drain frames one by one and then ask for last(); assertions in tests that empty an animation and still call last().","solutions":["Check count($image) > 0 before calling last()","If count() reported > 0 but last() still throws, the core is corrupted — re-read the source image","Avoid patterns that consume all frames then continue using the image"],"exampleFix":"// before\n$frame = $image->core()->last();\n\n// after\n$count = $image->count();\n$frame = $count > 0 ? $image->core()->last() : null;\nif ($frame === null) {\n    // handle empty animation\n}","handlingStrategy":"validation","validationCode":"$count = $image->count();\n$frame = $count > 0 ? $image->core()->last() : null;\nif ($frame === null) {\n    // handle empty animation explicitly\n}","typeGuard":"function hasFrames(ImageInterface $image): bool\n{\n    return $image->count() > 0;\n}","tryCatchPattern":"use Intervention\\Image\\Exceptions\\StateException;\n\ntry {\n    $frame = $image->core()->last();\n} catch (StateException $e) {\n    $image = $manager->read($source);\n    $frame = $image->core()->last();\n}","preventionTips":["Guard last() with count() > 0","Avoid pipelines that drain frames and still query the image afterwards","If count() > 0 but last() throws, re-read the source — the stack is corrupted"],"tags":["imagick","frames","state","empty-collection","animation"],"backgroundTag":"empty-frame-collection","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}