{"record":{"id":"b4c970506e86bd39","repo":"Intervention/image","slug":"frame","errorCode":null,"errorMessage":"Frame #","messagePattern":"Frame #","errorType":"exception","errorClass":"Intervention\\Image\\Exceptions\\InvalidArgumentException","httpStatus":null,"severity":"warning","filePath":"src/Drivers/Imagick/Core.php","lineNumber":344,"sourceCode":"     *\n     * @see CoreInterface::frame()\n     *\n     * @throws InvalidArgumentException\n     * @throws DriverException\n     */\n    public function frame(int $position): FrameInterface\n    {\n        foreach ($this->imagick as $core) {\n            try {\n                if ($core->getIteratorIndex() === $position) {\n                    return new Frame($core);\n                }\n            } catch (ImagickException | RuntimeException $e) {\n                throw new DriverException('Failed to load image frame a position ' . $position, previous: $e);\n            }\n        }\n\n        throw new InvalidArgumentException('Frame #' . $position . ' could not be found in the image');\n    }\n\n    /**\n     * {@inheritdoc}\n     *\n     * @see CoreInterface::loops()\n     *\n     * @throws DriverException\n     */\n    public function loops(): int\n    {\n        try {\n            return $this->imagick->getImageIterations();\n        } catch (ImagickException $e) {\n            throw new DriverException('Failed to get image loop count', previous: $e);\n        }\n    }\n","sourceCodeStart":326,"sourceCodeEnd":362,"githubUrl":"https://github.com/Intervention/image/blob/5598b9e39751c34afc5cdee84abef77f92c26f68/src/Drivers/Imagick/Core.php#L326-L362","documentation":"Thrown by Core::frame() when the whole frame stack was scanned but no frame sits at the requested position. Positions are zero-based, so any position < 0 or >= frame count ends here. This is a plain argument/range error, not a driver failure.","triggerScenarios":"Calling $image->core()->frame(10) on a 5-frame GIF; $image->removeAnimation(10) (or a numeric-string position like '80' that normalizes out of range for small animations); PixelColorAnalyzer with ->frame($i) beyond the frame count; first()/last() delegating to frame(0)/frame(count()-1) on an empty core (those rethrow as StateException).","commonSituations":"Hard-coded frame indices applied to animations of varying length; percentage positions like '90%' on short GIFs where normalizePosition() rounds to count(); off-by-one bugs after sliceAnimation() shrank the animation; loops using <= instead of <.","solutions":["Bounds-check against count($image) before requesting a frame","After slicing or removing animation frames, recompute indices from the new count()","For percentage-style positions, keep the value as a string like '50%' so the modifier normalizes it for the actual frame count"],"exampleFix":"// before: unguarded index\n$frame = $image->core()->frame($i);\n\n// after: bounds-checked\n$last = $image->count() - 1;\n$frame = $image->core()->frame(min(max(0, $i), $last));","handlingStrategy":"validation","validationCode":"$count = $image->count();\nif ($i < 0 || $i >= $count) {\n    throw new OutOfRangeException(\"frame {$i} requested, animation has {$count} frames\");\n}\n$frame = $image->core()->frame($i);","typeGuard":"function isValidFrameIndex(int $index, ImageInterface $image): bool\n{\n    return $index >= 0 && $index < $image->count();\n}","tryCatchPattern":"use Intervention\\Image\\Exceptions\\InvalidArgumentException;\n\ntry {\n    $frame = $image->core()->frame($i);\n} catch (InvalidArgumentException $e) {\n    $i = $image->count() - 1; // clamp to last frame\n    $frame = $image->core()->frame($i);\n}","preventionTips":["Always bounds-check indices against count($image)","Recompute indices after sliceAnimation() or removeAnimation()","Use loop conditions $i < $count, not $i <= $count"],"tags":["imagick","frames","index-out-of-range","animation"],"backgroundTag":"frame-index-out-of-range","analyzedSha":"5598b9e39751c34afc5cdee84abef77f92c26f68","analyzedAt":"2026-08-23T02:17:31.068Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}