dotnet/wpf · error · ArgumentException
SR.Animation_KeySpline_InvalidValue (controlPoint1)
Error message
SR.Animation_KeySpline_InvalidValue (controlPoint1)
What it means
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.
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).
Example fix
// before var spline = new KeySpline(new Point(0, 0), new Point(1.2, 0.9)); // after var p2 = new Point(Math.Clamp(1.2, 0, 1), Math.Clamp(0.9, 0, 1)); // -> (1.0, 0.9) var spline = new KeySpline(new Point(0, 0), p2);
Defensive patterns
Strategy: validation
Validate before calling
if (cp2.X < 0 || cp2.X > 1 || cp2.Y < 0 || cp2.Y > 1)
cp2 = new Point(Math.Clamp(cp2.X, 0, 1), Math.Clamp(cp2.Y, 0, 1));
var spline = new KeySpline(cp1, cp2); Type guard
static bool IsUnitPoint(Point p) => double.IsFinite(p.X) && double.IsFinite(p.Y) && p is { X: >= 0 and <= 1, Y: >= 0 and <= 1 }; Try / catch
try { spline = new KeySpline(cp1, cp2); }
catch (ArgumentException ex) when (ex.Message.Contains("controlPoint2"))
{
spline = new KeySpline(cp1, new Point(1, 1));
} Prevention
- 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
When it happens
Trigger: 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)).
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Animation_KeySpline_InvalidValue
- Enum_Invalid
- SR.Animation_Invalid_DefaultValue
- SR.Animation_KeySpline_InvalidValue (ControlPoint1)
- SR.Animation_KeySpline_InvalidValue (ControlPoint2)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/2a2a1fca2689553c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeySpline.cs:65
/// <summary>
/// Point constructor
/// </summary>
/// <param name="controlPoint1">the control point for the 0,0 endpoint</param>
/// <param name="controlPoint2">the control point for the 1,1 endpoint</param>
public KeySpline(Point controlPoint1, Point controlPoint2)
: base()
{
if (!IsValidControlPoint(controlPoint1))
{
throw new ArgumentException(SR.Format(
SR.Animation_KeySpline_InvalidValue,
"controlPoint1",
controlPoint1));
}
if (!IsValidControlPoint(controlPoint2))
{
throw new ArgumentException(SR.Format(
SR.Animation_KeySpline_InvalidValue,
"controlPoint2",
controlPoint2));
}
_controlPoint1 = controlPoint1;
_controlPoint2 = controlPoint2;
_isDirty = true;
}
#endregion Constructors
#region Freezable
/// <summary>
/// Implementation of <see cref="System.Windows.Freezable.CreateInstanceCore">Freezable.CreateInstanceCore</see>.
/// </summary>View on GitHub (pinned to 81131a70a4)