{"record":{"id":"03208d7058909303","repo":"dotnet/wpf","slug":"sr-animation-keytime-invalidpercentvalue","errorCode":null,"errorMessage":"SR.Animation_KeyTime_InvalidPercentValue","messagePattern":"SR\\.Animation_KeyTime_InvalidPercentValue","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeyTime.cs","lineNumber":30,"sourceCode":"    [TypeConverter(typeof(KeyTimeConverter))]\n    public struct KeyTime : IEquatable<KeyTime>\n    {\n        private object _value;\n        private KeyTimeType _type;\n        \n        #region Static Create Methods\n\n        /// <summary>\n        /// Creates a KeyTime that represents a Percent value.\n        /// </summary>\n        /// <param name=\"percent\">\n        /// The percent value provided as a double value between 0.0 and 1.0.\n        /// </param>\n        public static KeyTime FromPercent(double percent)\n        {\n            if (percent < 0.0 || percent > 1.0)\n            {\n                throw new ArgumentOutOfRangeException(nameof(percent), SR.Format(SR.Animation_KeyTime_InvalidPercentValue, percent));\n            }\n\n            KeyTime keyTime = new KeyTime\n            {\n                _value = percent,\n                _type = KeyTimeType.Percent\n            };\n\n            return keyTime;\n        }\n\n        /// <summary>\n        /// \n        /// </summary>\n        /// <param name=\"timeSpan\"></param>\n        public static KeyTime FromTimeSpan(TimeSpan timeSpan)\n        {\n            if (timeSpan < TimeSpan.Zero)","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeyTime.cs#L12-L48","documentation":"KeyTime.FromPercent throws ArgumentOutOfRangeException (SR.Animation_KeyTime_InvalidPercentValue) because a percent KeyTime must be a double between 0.0 and 1.0, where 1.0 equals 100% of the animation duration. Values outside that interval have no meaning for a percentage-based key time.","triggerScenarios":"KeyTime.FromPercent(p) where p < 0.0 or p > 1.0 — typically FromPercent(50) intended as 50%, or a negative fraction from a bad calculation.","commonSituations":"Confusing percent with percentage points (50 vs 0.5); computing fractions with wrong denominators; deserializing config that stores 0-100 scales; porting code from APIs that use 0-100 percents.","solutions":["Convert percentage points to a fraction before calling: KeyTime.FromPercent(pct / 100.0).","Clamp the value: Math.Clamp(fraction, 0.0, 1.0).","Validate input ranges at the config/UI layer (slider 0..1 or divide-by-100).","Catch ArgumentOutOfRangeException and fall back to KeyTime.FromPercent(0.5) or a TimeSpan-based key time."],"exampleFix":"// before\nvar kt = KeyTime.FromPercent(0.75 * 100); // 75.0 -> throws\n// after\nvar kt = KeyTime.FromPercent(0.75); // or KeyTime.FromPercent(pctPoints / 100.0)","handlingStrategy":"validation","validationCode":"if (percent < 0.0 || percent > 1.0)\n    throw new ArgumentOutOfRangeException(nameof(percent), \"Percent key time must be within [0.0, 1.0].\");\nvar kt = KeyTime.FromPercent(percent);","typeGuard":"static bool IsValidPercent(double p) => double.IsFinite(p) && p >= 0.0 && p <= 1.0;","tryCatchPattern":"try { kt = KeyTime.FromPercent(fraction); }\ncatch (ArgumentOutOfRangeException)\n{ kt = KeyTime.FromPercent(Math.Clamp(fraction, 0.0, 1.0)); }","preventionTips":["Divide 0-100 percentage inputs by 100 before FromPercent","Clamp all computed fractions with Math.Clamp(v, 0.0, 1.0)","Validate config-scaled values (many formats store percents as 0-100)","Add range assertions in key-frame building code"],"tags":["wpf","animation","keytime","range"],"backgroundTag":"argument-out-of-range","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}