dotnet/wpf · error · ArgumentNullException
SR.SCErasePath
Error message
SR.SCErasePath
What it means
StrokeCollection.Erase(IEnumerable<Point> eraserPath, StylusShape eraserShape) requires a non-null eraser path; a null path throws ArgumentNullException whose message is SR.SCErasePath. The path is the spine along which the eraser shape is swept to remove strokes. An empty path is a no-op, but null is rejected.
Solutions
- Guard: if (eraserPath == null) return; before calling Erase
- Ensure the stylus input handler always materializes a point collection, even if empty
- Pass an empty collection (which is a no-op) instead of null
Example fix
// before
strokes.Erase(path, shape); // path may be null
// after
if (path != null)
{
strokes.Erase(path, shape);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (eraserPath == null) return;
Type guard
bool HasPath(IEnumerable<Point> p) => p != null;
Try / catch
try { strokes.Erase(path, shape); } catch (ArgumentNullException) { /* no path captured: skip */ } Prevention
- Materialize point collections in the input handler before dispatching erase
- Pass empty collections (no-op) instead of null
- Audit nullability of point-collection parameters after refactors
When it happens
Trigger: Calling the shaped Erase overload with eraserPath == null, e.g. stylus points were never collected, or a nullable point collection variable was passed without a check.
Common situations: Erase triggered before any input points were captured; async processing where the path is produced later; porting code from an overload that accepted null silently.
Related errors
- SR.SCEraseShape
- SR.EventArgIsNull
- anchorLocator.Parts
- ArgumentNullException (buffer/sourceBuffer was IntPtr.Zero)
- ArgumentNullException: handle
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/60a646566daaa628.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection2.cs:322
}
}
/// <summary>
/// Erases all ink hit by the contour of an erasing stroke
/// </summary>
/// <param name="eraserShape">Shape of the eraser</param>
/// <param name="eraserPath">a path making the spine of the erasing stroke </param>
public void Erase(IEnumerable<Point> eraserPath, StylusShape eraserShape)
{
// Check the input parameters
if (eraserShape == null)
{
throw new System.ArgumentNullException(SR.SCEraseShape);
}
if (eraserPath == null)
{
throw new System.ArgumentNullException(SR.SCErasePath);
}
if (IEnumerablePointHelper.GetCount(eraserPath) == 0)
{
return;
}
ErasingStroke erasingStroke = new ErasingStroke(eraserShape, eraserPath);
for (int i = 0; i < this.Count; i++)
{
Stroke stroke = this[i];
List<StrokeIntersection> intersections = new List<StrokeIntersection>();
erasingStroke.EraseTest(StrokeNodeIterator.GetIterator(stroke, stroke.DrawingAttributes), intersections);
StrokeCollection eraseResult = stroke.Erase(intersections.ToArray());
UpdateStrokeCollection(stroke, eraseResult, ref i);
}
}View on GitHub (pinned to 81131a70a4)