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
- 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.
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
- Check Contains before every Insert/Add
- De-duplicate dictionary lists loaded from config
- Normalize Uri strings before comparison
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
- SR.CustomDictionaryNullItem
- SR.CustomDictionarySourcesUnsupportedURI
- ArgumentException: path
- ArgumentException: relativeTo
- ArgumentNullException: path
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)