dotnet/wpf · error · ArgumentException

SR.Animation_KeySpline_InvalidValue

Error message

SR.Animation_KeySpline_InvalidValue

What it means

The KeySpline(Point, Point) constructor throws ArgumentException (SR.Animation_KeySpline_InvalidValue) because KeySpline control points must lie in the unit square: each X and Y coordinate must be between 0.0 and 1.0 inclusive. This is required because a key spline defines a Bezier timing curve from (0,0) to (1,1).

Solutions

  1. Clamp both control points into [0,1] on each axis before constructing: Math.Clamp(v, 0.0, 1.0).
  2. Verify the units: control points are fractions of progress/time, not percentages.
  3. Validate inputs before construction with the same rule KeySpline uses (all coords within 0..1) and surface a friendly error.
  4. Wrap construction in try/catch (ArgumentException) and fall back to a known-good spline such as (0,0)-(1,1) (linear).

Example fix

// before
var spline = new KeySpline(new Point(0.4, 80), new Point(0.6, 95)); // percent values
// after
static Point Clamped(Point p) => new Point(Math.Clamp(p.X, 0, 1), Math.Clamp(p.Y, 0, 1));
var spline = new KeySpline(Clamped(new Point(0.4, 0.8)), Clamped(new Point(0.6, 0.95)));
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidControlPoint(Point p) => p.X >= 0 && p.X <= 1 && p.Y >= 0 && p.Y <= 1;
if (!IsValidControlPoint(cp1) || !IsValidControlPoint(cp2))
    throw new ArgumentException("KeySpline control points must be within [0,1] on both axes.");

Type guard

static Point ClampToUnitSquare(Point p) => new Point(Math.Clamp(p.X, 0.0, 1.0), Math.Clamp(p.Y, 0.0, 1.0));

Try / catch

KeySpline spline;
try { spline = new KeySpline(cp1, cp2); }
catch (ArgumentException)
{
    spline = new KeySpline(new Point(0, 0), new Point(1, 1)); // linear fallback
}

Prevention

When it happens

Trigger: new KeySpline(cp1, cp2) where either point has an X or Y coordinate < 0.0 or > 1.0 (e.g. new KeySpline(new Point(0.5, 1.5), new Point(0,0))).

Common situations: Building a KeySplineKeyFrame with easing parameters parsed from user config/XAML where values were percentages (0-100) instead of fractions (0-1); copying spline values from CSS cubic-bezier-like sources with out-of-range coordinates; arithmetic mistakes generating control points.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/fd253524bb3b6e1e. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Animation/KeySpline.cs:57

        /// <param name="y1">y value for the 0,0 endpoint's control point</param>
        /// <param name="x2">x value for the 1,1 endpoint's control point</param>
        /// <param name="y2">y value for the 1,1 endpoint's control point</param>
        public KeySpline(double x1, double y1, double x2, double y2)
            : this(new Point(x1, y1), new Point(x2, y2))
        {
        }

        /// <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;
        }

View on GitHub (pinned to 81131a70a4)