{"record":{"id":"2a2a1fca2689553c","repo":"dotnet/wpf","slug":"sr-animation-keyspline-invalidvalue-controlpoint1","errorCode":null,"errorMessage":"SR.Animation_KeySpline_InvalidValue (controlPoint1)","messagePattern":"SR\\.Animation_KeySpline_InvalidValue \\(controlPoint1\\)","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeySpline.cs","lineNumber":65,"sourceCode":"        /// <summary>\n        /// Point constructor\n        /// </summary>\n        /// <param name=\"controlPoint1\">the control point for the 0,0 endpoint</param>\n        /// <param name=\"controlPoint2\">the control point for the 1,1 endpoint</param>\n        public KeySpline(Point controlPoint1, Point controlPoint2)\n            : base()\n        {\n            if (!IsValidControlPoint(controlPoint1))\n            {\n                throw new ArgumentException(SR.Format(\n                    SR.Animation_KeySpline_InvalidValue,\n                    \"controlPoint1\",\n                    controlPoint1));\n            }\n\n            if (!IsValidControlPoint(controlPoint2))\n            {\n                throw new ArgumentException(SR.Format(\n                    SR.Animation_KeySpline_InvalidValue,\n                    \"controlPoint2\",\n                    controlPoint2));\n            }\n\n            _controlPoint1 = controlPoint1;\n            _controlPoint2 = controlPoint2;\n\n            _isDirty = true;\n        }\n\n        #endregion Constructors\n\n        #region Freezable\n\n        /// <summary>\n        /// Implementation of <see cref=\"System.Windows.Freezable.CreateInstanceCore\">Freezable.CreateInstanceCore</see>.\n        /// </summary>","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeySpline.cs#L47-L83","documentation":"This throw is the controlPoint2 branch of the same validation: the KeySpline(Point, Point) constructor rejects controlPoint2 when any of its X/Y coordinates is outside [0,1], raising ArgumentException with SR.Animation_KeySpline_InvalidValue and the parameter name 'controlPoint2'. Key spline control points must stay inside the unit square so the timing curve is monotone and bounded.","triggerScenarios":"new KeySpline(validCp1, cp2) where cp2.X or cp2.Y < 0.0 or > 1.0, e.g. new KeySpline(new Point(0,0), new Point(1.2, 0.9)).","commonSituations":"Same as the controlPoint1 case: percentages entered where fractions were expected, spline data loaded from external config/JSON, easing curves copied from other frameworks with different conventions.","solutions":["Clamp controlPoint2's X and Y into [0,1] before constructing the KeySpline.","Check which parameter failed: the exception argument name tells you controlPoint2 is the offender; fix that value's units/range.","Pre-validate with a helper (both coords in 0..1) and log/repair bad config values.","Catch ArgumentException and substitute a linear default spline (0,0)/(1,1)."],"exampleFix":"// before\nvar spline = new KeySpline(new Point(0, 0), new Point(1.2, 0.9));\n// after\nvar p2 = new Point(Math.Clamp(1.2, 0, 1), Math.Clamp(0.9, 0, 1)); // -> (1.0, 0.9)\nvar spline = new KeySpline(new Point(0, 0), p2);","handlingStrategy":"validation","validationCode":"if (cp2.X < 0 || cp2.X > 1 || cp2.Y < 0 || cp2.Y > 1)\n    cp2 = new Point(Math.Clamp(cp2.X, 0, 1), Math.Clamp(cp2.Y, 0, 1));\nvar spline = new KeySpline(cp1, cp2);","typeGuard":"static bool IsUnitPoint(Point p) => double.IsFinite(p.X) && double.IsFinite(p.Y) && p is { X: >= 0 and <= 1, Y: >= 0 and <= 1 };","tryCatchPattern":"try { spline = new KeySpline(cp1, cp2); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"controlPoint2\"))\n{\n    spline = new KeySpline(cp1, new Point(1, 1));\n}","preventionTips":["Read the exception's parameter name to see which control point is bad","Normalize percent-scaled config values by dividing by 100 before constructing","Clamp both points before the constructor call rather than one at a time","Add unit tests for spline parsing with out-of-range fixtures"],"tags":["wpf","animation","keyspline","argument-validation"],"backgroundTag":"invalid-argument-value","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"}