{"record":{"id":"2782911029c0cc40","repo":"dotnet/wpf","slug":"sr-customdictionaryitemalreadyexists","errorCode":null,"errorMessage":"SR.CustomDictionaryItemAlreadyExists","messagePattern":"SR\\.CustomDictionaryItemAlreadyExists","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/CustomDictionarySources.cs","lineNumber":92,"sourceCode":"\n        int IList<Uri>.IndexOf(Uri item)\n        {\n            return _uriList.IndexOf(item);\n        }\n\n        /// <summary>\n        /// Implementation of Insert method. A restriction added by this implementation is that\n        /// it will throw exception if the item was already added previously.\n        /// This is to avoid ambiguity in respect to the expected position (index) of the inserted item.\n        /// Caller will have to check first if item was already added.\n        /// </summary>\n        /// <param name=\"index\"></param>\n        /// <param name=\"item\"></param>\n        void IList<Uri>.Insert(int index, Uri item)\n        {\n            if (_uriList.Contains(item))\n            {\n                throw new ArgumentException(SR.CustomDictionaryItemAlreadyExists, nameof(item));\n            }\n\n            ValidateUri(item);\n            _uriList.Insert(index, item);\n            \n            Speller?.OnDictionaryUriAdded(item);\n        }\n\n        void IList<Uri>.RemoveAt(int index)\n        {\n            Uri uri = _uriList[index];\n            _uriList.RemoveAt(index);\n            \n            Speller?.OnDictionaryUriRemoved(uri);\n        }\n\n        /// <summary>\n        /// Sets value at specified index.","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/CustomDictionarySources.cs#L74-L110","documentation":"The IList<Uri>.Insert implementation of the custom-dictionary Uri collection rejects inserting a Uri that is already present in the list, throwing ArgumentException(SR.CustomDictionaryItemAlreadyExists). Spell-checking custom dictionaries must not contain duplicate sources, so duplicates are treated as an argument error rather than silently ignored.","triggerScenarios":"Calling Insert (or IList<Uri>.Insert) on a CustomDictionarySources collection with a Uri already added — e.g. adding the same lexicon file path twice, or adding a Uri that equals one loaded from a previously registered dictionary.","commonSituations":"Registering the same custom dictionary for multiple TextBoxes and re-adding the default lexicon, config that lists the same dictionary file twice, or merging dictionary lists from multiple sources without de-duplication.","solutions":["Check Contains(item) (or use the CustomDictionaryUriCollection wrapper) before calling Insert/Add.","Use a HashSet<string> of normalized path strings to track already-registered dictionary Uris.","Normalize casing/paths before comparing, since file Uris differing only by case may be considered equal or not depending on comparison.","Catch ArgumentException and skip the duplicate insert if duplicates are benign in your scenario."],"exampleFix":"// before\nuris.Insert(0, dictUri); // throws if already present\n// after\nif (!uris.Contains(dictUri)) uris.Insert(0, dictUri);","handlingStrategy":"validation","validationCode":"if (item == null || !lexicons.Contains(item))\n{\n    lexicons.Insert(0, item);\n}","typeGuard":"static bool IsNewDictionaryUri(IList<Uri> list, Uri item) => item != null && !list.Contains(item);","tryCatchPattern":"try\n{\n    lexicons.Insert(0, dictUri);\n}\ncatch (ArgumentException)\n{\n    // duplicate dictionary source; ignore or log\n}","preventionTips":["Check Contains before every Insert/Add","De-duplicate dictionary lists loaded from config","Normalize Uri strings before comparison"],"tags":["wpf","spellcheck","duplicate","dictionary"],"backgroundTag":"file-already-exists","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"}