{"record":{"id":"af0a0ae558ff78da","repo":"dotnet/wpf","slug":"duplicate-applicationgesture-values-are-not-allowed","errorCode":null,"errorMessage":"Duplicate ApplicationGesture values are not allowed.","messagePattern":"Duplicate ApplicationGesture values are not allowed\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/GestureRecognizer/NativeRecognizer.cs","lineNumber":230,"sourceCode":"            bool foundAllGestures = false;\n            List<ApplicationGesture> gestures = new List<ApplicationGesture>();\n            foreach (ApplicationGesture gesture in applicationGestures)\n            {\n                if (!ApplicationGestureHelper.IsDefined(gesture))\n                {\n                    throw new ArgumentException(SR.ApplicationGestureIsInvalid, nameof(applicationGestures));\n                }\n\n                //check for allgestures\n                if (gesture == ApplicationGesture.AllGestures)\n                {\n                    foundAllGestures = true;\n                }\n\n                //check for dupes\n                if (gestures.Contains(gesture))\n                {\n                    throw new ArgumentException(SR.DuplicateApplicationGestureFound, nameof(applicationGestures));\n                }\n\n                gestures.Add(gesture);\n            }\n\n            // AllGesture cannot be specified with other gestures\n            if (foundAllGestures && gestures.Count != 1)\n            {\n                // no dupes allowed\n                throw new ArgumentException(SR.AllGesturesMustExistAlone, nameof(applicationGestures));\n            }\n\n            return gestures.ToArray();\n        }\n\n        #endregion Internal Methods\n\n        //-------------------------------------------------------------------------------","sourceCodeStart":212,"sourceCodeEnd":248,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/GestureRecognizer/NativeRecognizer.cs#L212-L248","documentation":"The same validation pass (GetApplicationGestureArrayAndVerify) rejects duplicates: it accumulates gestures in a list and throws ArgumentException (SR.DuplicateApplicationGestureFound) if a gesture already appeared, since the native context expects a set of unique gesture IDs.","triggerScenarios":"Assigning EnabledGestures where the same ApplicationGesture appears more than once — e.g. appending defaults to user-selected gestures, or concatenating multiple gesture lists.","commonSituations":"Merging saved preferences with hardcoded defaults; unioning gesture lists without deduplication.","solutions":["Deduplicate before assigning: pass through Distinct()","Use HashSet<ApplicationGesture> to build the set","Normalize/merge gesture lists at load time before configuring the recognizer"],"exampleFix":"// before\nrecognizer.EnabledGestures = userGestures.Concat(defaults).ToArray();\n// after\nrecognizer.EnabledGestures = userGestures.Concat(defaults).Distinct().ToArray();","handlingStrategy":"validation","validationCode":"gestures = gestures.Distinct().ToArray(); // dedupe before assignment","typeGuard":"static ApplicationGesture[] Deduped(ApplicationGesture[] g) => g == null ? g : g.Distinct().ToArray();","tryCatchPattern":"try { recognizer.EnabledGestures = gestures; }\ncatch (ArgumentException) { recognizer.EnabledGestures = gestures.Distinct().ToArray(); }","preventionTips":["Build gesture sets with HashSet<ApplicationGesture>","Deduplicate whenever merging saved preferences with defaults","Treat EnabledGestures as a set, not a list"],"tags":["wpf","ink","argument-validation","duplicates"],"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"}