{"record":{"id":"30bcd662110e2581","repo":"HandyOrg/HandyControl","slug":"invalidframe","errorCode":null,"errorMessage":"InvalidFrame","messagePattern":"InvalidFrame","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs","lineNumber":36,"sourceCode":"\n    public bool Animated { get; }\n\n    public EventHandler FrameChangedHandler { get; set; }\n\n    internal int FrameTimer { get; set; }\n\n    public bool FrameDirty { get; private set; }\n\n    public int Frame\n    {\n        get => _frame;\n        set\n        {\n            if (_frame != value)\n            {\n                if (value < 0 || value >= FrameCount)\n                {\n                    throw new ArgumentException(\"InvalidFrame\");\n                }\n\n                if (Animated)\n                {\n                    _frame = value;\n                    FrameDirty = true;\n\n                    OnFrameChanged(EventArgs.Empty);\n                }\n            }\n        }\n    }\n\n    public GifImageInfo(GifImage image)\n    {\n        Image = image;\n        Animated = ImageAnimator.CanAnimate(image);\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/HandyOrg/HandyControl/blob/2c0875ebd67326e0c67282967e3e809c69282fee/src/Shared/HandyControl_Shared/Data/Gif/GifImageInfo.cs#L18-L54","documentation":"The GifImageInfo.Frame property setter validates the requested frame index against FrameCount and throws ArgumentException(\"InvalidFrame\") when the value is negative or >= FrameCount. The GIF decoder in HandyControl only exposes frames that actually exist in the source image, so any out-of-range index is rejected before mutating internal state.","triggerScenarios":"Setting GifImageInfo.Frame to a negative number, or to a value equal to or greater than FrameCount (e.g. Frame = FrameCount, forgetting indices are 0-based).","commonSituations":"Programmatically seeking an animated GIF to its last frame using a 1-based index; caching FrameCount before the GIF metadata finished loading (FrameCount still 0); data-binding a frame slider whose maximum is off by one.","solutions":["Clamp the value before assigning: frame = Math.Max(0, Math.Min(value, info.FrameCount - 1)).","Ensure the GIF metadata is loaded (FrameCount > 0) before setting Frame; for non-animated GIFs do not set Frame at all.","Use 0-based indexing: the first frame is 0, the last is FrameCount - 1."],"exampleFix":"// before\ngifInfo.Frame = gifInfo.FrameCount; // last frame?\n// after\nif (gifInfo.FrameCount > 0)\n    gifInfo.Frame = gifInfo.FrameCount - 1;","handlingStrategy":"validation","validationCode":"if (gifInfo != null && frameIndex >= 0 && frameIndex < gifInfo.FrameCount)\n    gifInfo.Frame = frameIndex;","typeGuard":"static bool IsValidFrame(HandyControl.Data.Gif.GifImageInfo info, int frame) => info != null && info.FrameCount > 0 && frame >= 0 && frame < info.FrameCount;","tryCatchPattern":"try { gifInfo.Frame = requestedFrame; } catch (ArgumentException ex) when (ex.Message == \"InvalidFrame\") { gifInfo.Frame = 0; // safe reset\n}","preventionTips":["Always clamp frame indices: Math.Max(0, Math.Min(i, FrameCount - 1)).","Check FrameCount > 0 before setting Frame; non-animated GIFs have no settable frame.","Remember frames are 0-based; the last valid index is FrameCount - 1."],"tags":["gif","argument","out-of-range","index"],"backgroundTag":"argument-out-of-range","analyzedSha":"2c0875ebd67326e0c67282967e3e809c69282fee","analyzedAt":"2026-09-14T14:45:29.754Z","contentChangedAt":"2026-09-14T14:45:29.754Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}