dotnet/wpf · error · ArgumentNullException
SR.EmptyScToReplaceWith
Error message
SR.EmptyScToReplaceWith
What it means
StrokeCollection.Replace(StrokeCollection, StrokeCollection) throws ArgumentException with SR.EmptyScToReplace when strokesToReplace is non-null but empty (Count == 0). An empty replacement set identifies no strokes, so the replace operation is undefined and rejected.
Solutions
- Guard with if (strokesToReplace.Count > 0) before calling Replace.
- Only invoke Replace when a prior operation (selection, hit test) actually produced strokes.
- Catch ArgumentException and treat it as a no-op in idempotent UI flows.
Example fix
// before
strokes.Replace(selectedStrokes, replacement); // selectedStrokes.Count == 0
// after
if (selectedStrokes.Count > 0)
strokes.Replace(selectedStrokes, replacement); Defensive patterns
Strategy: validation
Validate before calling
if (strokesToReplace != null && strokesToReplace.Count > 0)
strokes.Replace(strokesToReplace, strokesToReplaceWith); Type guard
static bool IsNonEmpty(StrokeCollection c) => c != null && c.Count > 0;
Try / catch
try { strokes.Replace(strokesToReplace, with); }
catch (ArgumentException ex) when (ex.ParamName == "strokesToReplace") { /* empty set: no-op */ } Prevention
- Check Count > 0 on selection-derived collections before Replace.
- Re-check selection state immediately before replacing (it may have been cleared by a UI event).
- Treat empty replace sets as idempotent no-ops in UI code.
When it happens
Trigger: Calling Replace with a StrokeCollection constructed but never populated (new StrokeCollection()), or with a filtered subset that ended up empty (e.g. selected strokes after the selection was cleared).
Common situations: Replace-on-selection workflows where InkCanvas.GetSelectedStrokes() returned an empty collection; building the replace set inside a loop that never executed due to a predicate mismatch.
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
- SR.EmptyArray
- SR.EmptyArray
- SR.EmptyArrayNotAllowedAsArgument
- SR.EmptyScToReplace
- SR.InvalidStylusPointCollectionZeroCount
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/bfd168424f4e840b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs:469
StrokeCollection strokesToReplace = new StrokeCollection();
strokesToReplace.Add(strokeToReplace);
this.Replace(strokesToReplace, strokesToReplaceWith);
}
/// <summary>
/// Replace
/// </summary>
/// <param name="strokesToReplace"></param>
/// <param name="strokesToReplaceWith"></param>
public void Replace(StrokeCollection strokesToReplace, StrokeCollection strokesToReplaceWith)
{
if ( strokesToReplace == null )
{
throw new ArgumentNullException(SR.EmptyScToReplace);
}
if ( strokesToReplaceWith == null )
{
throw new ArgumentNullException(SR.EmptyScToReplaceWith);
}
int replaceCount = strokesToReplace.Count;
if ( replaceCount == 0 )
{
ArgumentException ae = new ArgumentException(SR.EmptyScToReplace, nameof(strokesToReplace));
//
// we add a tag here so we can check for this in EraserBehavior.OnPointEraseResultChanged
// to determine if this method is the origin of an ArgumentException we harden against
//
ae.Data.Add("System.Windows.Ink.StrokeCollection", "");
throw ae;
}
int[] indexes = this.GetStrokeIndexes(strokesToReplace);
if ( indexes == null )
{
// At least one stroke doesn't exist in our collection. We throw.View on GitHub (pinned to 81131a70a4)