dotnet/wpf · error · ArgumentException
SR.StrokeIsDuplicated
Error message
SR.StrokeIsDuplicated
What it means
The StrokeCollection(IEnumerable<Stroke> strokes) constructor copies the input while checking for duplicates; if the same Stroke instance appears twice, it clears the partially built collection and throws ArgumentException(SR.StrokeIsDuplicated) naming the strokes parameter. Stroke instances must be unique within a collection.
Solutions
- De-duplicate the input before constructing: new StrokeCollection(input.Distinct())
- Build via AddRange on an existing StrokeCollection and handle duplicates yourself
- Check for duplicates manually (items.Contains) before constructing
Example fix
// before var sc = new StrokeCollection(selectedStrokes); // after var sc = new StrokeCollection(selectedStrokes.Distinct());
Defensive patterns
Strategy: validation
Validate before calling
bool hasDuplicates = strokes is not null && strokes.GroupBy(s => s).Any(g => g.Count() > 1);
Type guard
static bool AreDistinct(IEnumerable<Stroke>? list) => list is not null && list.Distinct().Count() == list.Count();
Try / catch
try { var sc = new StrokeCollection(strokes); } catch (ArgumentException ex) when (ex.Message.Contains("duplicate")) { var sc = new StrokeCollection(strokes.Distinct()); } Prevention
- Apply .Distinct() before constructing StrokeCollection
- Avoid adding the same Stroke instance to a collection twice
- Track selected strokes in a HashSet<Stroke>
When it happens
Trigger: Calling new StrokeCollection(strokes) where strokes contains the same Stroke reference twice, e.g. a list built by adding an already-present stroke, or union of two overlapping selections without deduplication.
Common situations: Merging selections from multiple strokes' hit tests; concatenating StrokeCollections and passing the result to the constructor; Distinct() omitted from LINQ pipelines.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- ArgumentOutOfRangeException(nameof(oldProperty))
- ArgumentOutOfRangeException(nameof(percentageWithinBounds))
- ArgumentOutOfRangeException(nameof(percentageWithinLasso))
- ArgumentOutOfRangeException(percentageWithinBounds)
- ArgumentOutOfRangeException(percentageWithinLasso)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/25f7cc468e8c5997.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/StrokeCollection.cs:47
public StrokeCollection()
{
}
/// <summary>Creates a StrokeCollection based on a collection of existing strokes</summary>
public StrokeCollection(IEnumerable<Stroke> strokes)
{
ArgumentNullException.ThrowIfNull(strokes);
List<Stroke> items = (List<Stroke>)this.Items;
//unfortunately we have to check for dupes with this ctor
foreach ( Stroke stroke in strokes )
{
if ( items.Contains(stroke) )
{
//clear and throw
items.Clear();
throw new ArgumentException(SR.StrokeIsDuplicated, nameof(strokes));
}
items.Add(stroke);
}
}
/// <summary>Creates a collection from ISF data in the specified stream</summary>
/// <param name="stream">Stream of ISF data</param>
public StrokeCollection(Stream stream)
{
ArgumentNullException.ThrowIfNull(stream);
if ( !stream.CanRead )
{
throw new ArgumentException(SR.Image_StreamRead, nameof(stream));
}
Stream seekableStream = GetSeekableStream(stream);
if (seekableStream == null)
{View on GitHub (pinned to 81131a70a4)