{"record":{"id":"ed001fc7192ce1ea","repo":"dotnet/wpf","slug":"sr-invalidstyluspointdescriptionduplicatesfound","errorCode":null,"errorMessage":"SR.InvalidStylusPointDescriptionDuplicatesFound","messagePattern":"SR\\.InvalidStylusPointDescriptionDuplicatesFound","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPointDescription.cs","lineNumber":71,"sourceCode":"                infos[RequiredPressureIndex].Id != StylusPointPropertyIds.NormalPressure)\n            {\n                throw new ArgumentException(SR.InvalidStylusPointDescription, nameof(stylusPointPropertyInfos));\n            }\n\n            //\n            // look for duplicates, validate that buttons are last\n            //\n            List<Guid> seenIds = new List<Guid>();\n            seenIds.Add(StylusPointPropertyIds.X);\n            seenIds.Add(StylusPointPropertyIds.Y);\n            seenIds.Add(StylusPointPropertyIds.NormalPressure);\n\n            int buttonCount = 0;\n            for (int x = RequiredCountOfProperties; x < infos.Count; x++)\n            {\n                if (seenIds.Contains(infos[x].Id))\n                {\n                    throw new ArgumentException(SR.InvalidStylusPointDescriptionDuplicatesFound, nameof(stylusPointPropertyInfos));\n                }\n                if (infos[x].IsButton)\n                {\n                    buttonCount++;\n                }\n                else\n                {\n                    //this is not a button, make sure we haven't seen one before\n                    if (buttonCount > 0)\n                    {\n                        throw new ArgumentException(SR.InvalidStylusPointDescriptionButtonsMustBeLast, nameof(stylusPointPropertyInfos));\n                    }\n                }\n                seenIds.Add(infos[x].Id);\n            }\n            if (buttonCount > MaximumButtonCount)\n            {\n                throw new ArgumentException(SR.InvalidStylusPointDescriptionTooManyButtons, nameof(stylusPointPropertyInfos));","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/StylusPointDescription.cs#L53-L89","documentation":"The StylusPointDescription constructor rejects duplicate property IDs beyond the required X/Y/pressure trio. Each StylusPointProperty Guid must appear at most once, because properties are stored in a flat array and looked up by ID; duplicates would make indexing ambiguous. This ArgumentException names stylusPointPropertyInfos as the offending parameter.","triggerScenarios":"Calling new StylusPointDescription(stylusPointPropertyInfos) where any of infos[3..] repeats a Guid that was already seen (or repeats X/Y/pressure IDs).","commonSituations":"Merging two device description lists and appending a property that is already present; adding a button property whose Guid equals an existing property Guid; generating infos in a loop that adds the same custom property per data field.","solutions":["De-duplicate the collection before constructing, e.g. filter with a HashSet<Guid> on each info's Id.","Check that button property Guids (e.g. StylusPointPropertyIds.TipButton, BarrelButton) are each added only once.","When merging descriptions, use StylusPointDescription.GetStylusPointProperties() and Distinct() by Id."],"exampleFix":"// before\nvar desc = new StylusPointDescription(new[]{ infoX, infoY, infoPressure, tipButton, tipButton });\n// after\nvar seen = new HashSet<Guid>();\nvar unique = allInfos.Where(i => seen.Add(i.Id)).ToArray();\nvar desc = new StylusPointDescription(unique);","handlingStrategy":"validation","validationCode":"var seen = new HashSet<Guid>();\nbool hasDuplicates = infos.Any(i => !seen.Add(i.Id));","typeGuard":null,"tryCatchPattern":"try { var desc = new StylusPointDescription(infos); }\ncatch (ArgumentException) { infos = infos.GroupBy(i => i.Id).Select(g => g.First()).ToArray(); desc = new StylusPointDescription(infos); }","preventionTips":["De-duplicate by Id before constructing","Never add the same button Guid twice","Use DistinctBy(i => i.Id) when merging sources"],"tags":["wpf","stylus","duplicate","argument-exception"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}