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

  1. De-duplicate the input before constructing: new StrokeCollection(input.Distinct())
  2. Build via AddRange on an existing StrokeCollection and handle duplicates yourself
  3. 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

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


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)