AvaloniaUI/Avalonia · error · ArgumentException

{nameof(KeySpline)} must have X coordinates >= 0.0 and <= 1.

Error message

{nameof(KeySpline)} must have X coordinates >= 0.0 and <= 1.0.

What it means

Thrown when assigning a KeySpline to a KeyFrame whose X control coordinates are outside the [0.0, 1.0] range. A KeySpline models a cubic-bezier easing curve where the X axis is normalized time, so X must stay in [0,1]; Y is unconstrained. The setter stores the value first, then calls IsValid() (which only checks X1 and X2) and throws on failure.

Source

Thrown at src/Avalonia.Base/Animation/KeyFrame.cs:94

            }
        }

        /// <summary>
        /// Gets or sets the KeySpline of this <see cref="KeyFrame"/>.
        /// </summary>
        /// <value>The key spline.</value>
        public KeySpline? KeySpline
        {
            get
            {
                return _kKeySpline;
            }
            set
            {
                _kKeySpline = value;
                if (value != null && !value.IsValid())
                {
                    throw new ArgumentException($"{nameof(KeySpline)} must have X coordinates >= 0.0 and <= 1.0.");
                }
            }
        }

        internal override void BuildDebugDisplay(StringBuilder builder, bool includeContent)
        {
            base.BuildDebugDisplay(builder, includeContent);

            switch (TimingMode)
            {
                case KeyFrameTimingMode.TimeSpan:
                    DebugDisplayHelper.AppendOptionalValue(builder, nameof(KeyTime), KeyTime, includeContent);
                    break;
                case KeyFrameTimingMode.Cue:
                    DebugDisplayHelper.AppendOptionalValue(builder, nameof(Cue), Cue, includeContent);
                    break;
            }
        }

View on GitHub (pinned to 11c5427268)

Solutions

  1. Ensure ControlPointX1 and ControlPointX2 are both within 0.0 and 1.0 inclusive.
  2. If you only want to shape progress, vary Y1/Y2 and keep X1/X2 in range (e.g. use 0.42,0,0.58,1 for ease-in-out).
  3. Call keySpline.IsValid() yourself before assigning it to KeyFrame.KeySpline to get a clean boolean.

Example fix

// before
frame.KeySpline = new KeySpline(1.5, 0.0, 0.5, 1.0); // X1=1.5 out of range

// after
frame.KeySpline = new KeySpline(0.42, 0.0, 0.58, 1.0);
Defensive patterns

Strategy: validation

Validate before calling

static bool TrySetKeySpline(KeyFrame frame, KeySpline spline)
{
    if (spline is null || !spline.IsValid()) return false;
    frame.KeySpline = spline;
    return true;
}

Type guard

static bool IsValidKeySpline(KeySpline? s) =>
    s is not null && s.ControlPointX1 >= 0.0 && s.ControlPointX1 <= 1.0
                  && s.ControlPointX2 >= 0.0 && s.ControlPointX2 <= 1.0;

Try / catch

try { frame.KeySpline = spline; }
catch (ArgumentException ex) when (ex.Message.Contains("X coordinates"))
{ /* log and clamp or fall back to a known-good spline */ }

Prevention

When it happens

Trigger: Setting KeyFrame.KeySpline to a KeySpline instance constructed or mutated with ControlPointX1 or ControlPointX2 outside [0,1]; or parsing a KeySpline string like "1.5,0,0.5,1" and assigning it to a key frame.

Common situations: Hand-typing an easing curve in XAML or code-behind and overshooting an X coordinate; importing WPF/CSS cubic-bezier values without clamping; confusing the X (time) and Y (progress) axes.

Related errors


AI-assisted analysis of AvaloniaUI/Avalonia@11c5427268 (2026-08-13). Data as JSON: /api/errors/33f47b761412ecdf. Report an issue: GitHub.