dotnet/wpf · error · ArgumentException

SR.CustomDictionaryItemAlreadyExists

Error message

SR.CustomDictionaryItemAlreadyExists

What it means

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.

Solutions

  1. Check Contains(item) (or use the CustomDictionaryUriCollection wrapper) before calling Insert/Add.
  2. Use a HashSet<string> of normalized path strings to track already-registered dictionary Uris.
  3. Normalize casing/paths before comparing, since file Uris differing only by case may be considered equal or not depending on comparison.
  4. Catch ArgumentException and skip the duplicate insert if duplicates are benign in your scenario.

Example fix

// before
uris.Insert(0, dictUri); // throws if already present
// after
if (!uris.Contains(dictUri)) uris.Insert(0, dictUri);
Defensive patterns

Strategy: validation

Validate before calling

if (item == null || !lexicons.Contains(item))
{
    lexicons.Insert(0, item);
}

Type guard

static bool IsNewDictionaryUri(IList<Uri> list, Uri item) => item != null && !list.Contains(item);

Try / catch

try
{
    lexicons.Insert(0, dictUri);
}
catch (ArgumentException)
{
    // duplicate dictionary source; ignore or log
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/2782911029c0cc40. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/CustomDictionarySources.cs:92

        int IList<Uri>.IndexOf(Uri item)
        {
            return _uriList.IndexOf(item);
        }

        /// <summary>
        /// Implementation of Insert method. A restriction added by this implementation is that
        /// it will throw exception if the item was already added previously.
        /// This is to avoid ambiguity in respect to the expected position (index) of the inserted item.
        /// Caller will have to check first if item was already added.
        /// </summary>
        /// <param name="index"></param>
        /// <param name="item"></param>
        void IList<Uri>.Insert(int index, Uri item)
        {
            if (_uriList.Contains(item))
            {
                throw new ArgumentException(SR.CustomDictionaryItemAlreadyExists, nameof(item));
            }

            ValidateUri(item);
            _uriList.Insert(index, item);
            
            Speller?.OnDictionaryUriAdded(item);
        }

        void IList<Uri>.RemoveAt(int index)
        {
            Uri uri = _uriList[index];
            _uriList.RemoveAt(index);
            
            Speller?.OnDictionaryUriRemoved(uri);
        }

        /// <summary>
        /// Sets value at specified index.

View on GitHub (pinned to 81131a70a4)