{"record":{"id":"85b653a576bb9ee3","repo":"AvaloniaUI/Avalonia","slug":"key-frame-key-key-is-less-than-the-previous-one","errorCode":null,"errorMessage":"Key frame key {key} is less than the previous one","messagePattern":"Key frame key (.+?) is less than the previous one","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Rendering/Composition/Animations/KeyFrames.cs","lineNumber":20,"sourceCode":"using System.Collections.Generic;\nusing Avalonia.Animation.Easings;\nusing Avalonia.Rendering.Composition.Expressions;\n\nnamespace Avalonia.Rendering.Composition.Animations\n{\n    \n    /// <summary>\n    /// Collection of composition animation key frames\n    /// </summary>\n    /// <typeparam name=\"T\"></typeparam>\n    class KeyFrames<T> : List<KeyFrame<T>>, IKeyFrames\n    {\n        void Validate(float key)\n        {\n            if (key < 0 || key > 1)\n                throw new ArgumentException(\"Key frame key\");\n            if (Count > 0 && this[Count - 1].NormalizedProgressKey > key)\n                throw new ArgumentException(\"Key frame key \" + key + \" is less than the previous one\");\n        }\n        \n        public void InsertExpressionKeyFrame(float normalizedProgressKey, string value, IEasing easingFunction)\n        {\n            Validate(normalizedProgressKey);\n            Add(new KeyFrame<T>\n            {\n                NormalizedProgressKey = normalizedProgressKey,\n                Expression = Expression.Parse(value),\n                EasingFunction = easingFunction\n            });\n        }\n\n        public void Insert(float normalizedProgressKey, T value, IEasing easingFunction)\n        {\n            Validate(normalizedProgressKey);\n            Add(new KeyFrame<T>\n            {","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Rendering/Composition/Animations/KeyFrames.cs#L2-L38","documentation":"Thrown by KeyFrames<T>.Validate when a newly inserted key frame has a lower normalizedProgressKey than the last (highest) key already in the collection. Key frames must be added in non-decreasing time order so the animation can interpolate forward.","triggerScenarios":"Inserting frames out of order, e.g. InsertKeyFrame(0.5f,...) followed by InsertKeyFrame(0.25f,...). The message includes the offending key value.","commonSituations":"Data-driven key frames sourced from an unsorted collection; inserting a 'starting' frame at 0 after already adding 0.5/1.0; loop that adds frames in reverse.","solutions":["Insert key frames in ascending progress order.","Sort your frame data by progress key before inserting.","If you need a frame before the current last one, rebuild the animation from scratch in order."],"exampleFix":"// before\nanim.InsertKeyFrame(0.5f, mid);\nanim.InsertKeyFrame(0.25f, early); // throws: 0.25 < 0.5\n// after\nanim.InsertKeyFrame(0.25f, early);\nanim.InsertKeyFrame(0.5f, mid);","handlingStrategy":"validation","validationCode":"// ensure frames are in ascending key order before inserting\nforeach (var f in frames.OrderBy(f => f.Key)) anim.InsertKeyFrame(f.Key, f.Value);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Insert key frames in non-decreasing progress order.","Sort frame data by key before insertion.","Rebuild the animation from scratch if you need to prepend a frame."],"tags":["animation","composition","key-frames","ordering","argument-validation"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}