dotnet/wpf · error · ArgumentOutOfRangeException

SR.InvalidStylusPointXYNaN

Error message

SR.InvalidStylusPointXYNaN

What it means

The StylusPoint constructor throws ArgumentOutOfRangeException when the x coordinate is double.NaN. StylusPoint coordinates must be real numbers; NaN cannot be represented in packet data, so the constructor rejects it before clamping. This guard exists because NaN silently corrupts downstream geometry and hit-testing.

Solutions

  1. Check double.IsNaN(x) before constructing the StylusPoint and substitute a valid value or skip the point.
  2. Trace the origin of the x value (division, Math operations, external data) and fix the source that produces NaN.
  3. Catch ArgumentOutOfRangeException if NaN input is expected and handle the point as invalid.

Example fix

// before
var point = new StylusPoint(rawX, rawY);
// after
if (!double.IsNaN(rawX) && !double.IsNaN(rawY))
{
    var point = new StylusPoint(rawX, rawY);
}
Defensive patterns

Strategy: validation

Validate before calling

if (double.IsNaN(x)) throw new ArgumentException("x must be a finite value");
var point = new StylusPoint(x, y);

Type guard

static bool IsValidX(double x) => !double.IsNaN(x) && !double.IsInfinity(x);

Try / catch

try { var p = new StylusPoint(x, y); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "x") { /* treat point as invalid */ }

Prevention

When it happens

Trigger: Calling new StylusPoint(x, y) or new StylusPoint(x, y, pressureFactor, stylusPointDescription, additionalValues, ...) with a double.NaN value for the x parameter.

Common situations: Computing coordinates from division or transforms that yield NaN (e.g. 0/0 from a scale calculation), or passing through unvalidated sensor/digitizer data where a missing sample is encoded as NaN.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPoint.cs:72

            : this(x, y, pressureFactor, stylusPointDescription, additionalValues, true, true)
        {
        }

        /// <summary>
        /// internal ctor
        /// </summary>
        internal StylusPoint(   
            double x, 
            double y, 
            float pressureFactor, 
            StylusPointDescription stylusPointDescription, 
            int[] additionalValues, 
            bool validateAdditionalData,
            bool validatePressureFactor)
        {
            if (Double.IsNaN(x))
            {
                throw new ArgumentOutOfRangeException(nameof(x), SR.InvalidStylusPointXYNaN);
            }
            if (Double.IsNaN(y))
            {
                throw new ArgumentOutOfRangeException(nameof(y), SR.InvalidStylusPointXYNaN);
            }


            //we don't validate pressure when called by StylusPointDescription.Reformat
            if (validatePressureFactor &&
                (pressureFactor == Single.NaN || pressureFactor < 0.0f || pressureFactor > 1.0f))
            {
                throw new ArgumentOutOfRangeException(nameof(pressureFactor), SR.InvalidPressureValue);
            }
            //
            // only accept values between MaxXY and MinXY
            // we don't throw when passed a value outside of that range, we just silently trunctate
            //
            _x = GetClampedXYValue(x);

View on GitHub (pinned to 81131a70a4)