dotnet/wpf · error · ArgumentException

SR.EmptyArray

Error message

SR.EmptyArray

What it means

Stroke.GetClipResult(IEnumerable<Point> lassoPoints) builds a lasso to hit-test the stroke, and an empty point list cannot form a lasso. The library throws ArgumentException(SR.EmptyArray) when the collection has zero points. Callers must supply at least one Point.

Solutions

  1. Check lassoPoints.Count() > 0 before calling GetClipResult
  2. Return early or skip clipping when the user's lasso gesture has fewer than 1 point
  3. Fall back to GetClipResult with a default bounding region when no points exist

Example fix

// before
StrokeCollection clipped = stroke.GetClipResult(lassoPoints);
// after
var pts = lassoPoints.ToList();
if (pts.Count == 0) return;
StrokeCollection clipped = stroke.GetClipResult(pts);
Defensive patterns

Strategy: validation

Validate before calling

bool canClip = lassoPoints is not null && lassoPoints.Any();

Type guard

static bool HasPoints(IEnumerable<Point>? pts) => pts is not null && pts.Any();

Try / catch

try { result = stroke.GetClipResult(pts); } catch (ArgumentException ex) when (ex.ParamName == "lassoPoints") { result = new StrokeCollection(); }

Prevention

When it happens

Trigger: Calling GetClipResult with an empty Point[] or empty IEnumerable<Point>; collecting lasso points from user input that produced no points before calling the API.

Common situations: Mouse/stylus handlers that call GetClipResult on a drag that never moved; LINQ filtering that yielded an empty point sequence.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Stroke2.cs:120

        public StrokeCollection GetClipResult(Rect bounds)
        {
            return this.GetClipResult(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
        }


        /// <summary>
        /// Clip with lasso. Calculate the after-clipping Strokes. Only the "in-segments" are left after this operation.
        /// </summary>
        /// <param name="lassoPoints">The lasso points to clip with</param>
        /// <returns>The after-clipping strokes</returns>
        public StrokeCollection GetClipResult(IEnumerable<Point> lassoPoints)
        {
            // Check the input parameters
            ArgumentNullException.ThrowIfNull(lassoPoints);

            if (IEnumerablePointHelper.GetCount(lassoPoints) == 0)
            {
                throw new ArgumentException(SR.EmptyArray);
            }

            Lasso lasso = new SingleLoopLasso();
            lasso.AddPoints(lassoPoints);
            return this.Clip(this.HitTest(lasso));
        }


        /// <summary>
        /// Erase with a rect. Calculate the after-erasing Strokes. Only the "out-segments" are left after this operation.
        /// </summary>
        /// <param name="bounds">A Rect to clip with</param>
        /// <returns>The after-erasing strokes</returns>
        public StrokeCollection GetEraseResult(Rect bounds)
        {
            return this.GetEraseResult(new Point[4] { bounds.TopLeft, bounds.TopRight, bounds.BottomRight, bounds.BottomLeft });
        }

View on GitHub (pinned to 81131a70a4)