dotnet/wpf · error · ArgumentException

SR.Format(SR.CollectionDuplicateKey, key)

Error message

SR.Format(SR.CollectionDuplicateKey, key)

What it means

CharacterMetricsDictionary.Add(key, value) must not overwrite an existing entry. SetValue is invoked with failIfExists=true from Add; if a CharacterMetrics already exists for that code point, an ArgumentException (CollectionDuplicateKey) is thrown. (The indexer uses failIfExists=false and silently overwrites instead.)

Solutions

  1. Check dictionary.ContainsKey(key) (or the indexer != null) before calling Add.
  2. Use the indexer assignment dict[key] = value if overwrite is intended.
  3. Deduplicate the source metrics table by code point before populating.

Example fix

// before
dict[0x41] = metricsA;
dict.Add(0x41, metricsB); // throws
// after
if (!dict.ContainsKey(0x41)) dict.Add(0x41, metricsB);
Defensive patterns

Strategy: validation

Validate before calling

if (!dict.ContainsKey(key))
    dict.Add(key, value);

Try / catch

try { dict.Add(key, value); }
catch (ArgumentException ex) { /* key already present; overwrite or log */ }

Prevention

When it happens

Trigger: Calling dictionary.Add(key, value) when key already has an entry — e.g. adding metrics for the same code point twice, or re-running an initialization pass without clearing the dictionary.

Common situations: Populating the dictionary from a font metrics table that contains duplicate code points; idempotency bugs where setup code runs twice; assuming Add behaves like the indexer.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/CharacterMetricsDictionary.cs:363

                _pageTable = new CharacterMetrics[PageCount][];
                _pageTable[i] = page = new CharacterMetrics[PageSize];
            }

            return page;
        }

        private void SetValue(int key, CharacterMetrics value, bool failIfExists)
        {
            if (key < 0 || key > LastDeviceFontCharacterCode)
                throw new ArgumentOutOfRangeException(SR.Format(SR.CodePointOutOfRange, key));

            ArgumentNullException.ThrowIfNull(value);

            CharacterMetrics[] page = GetPageFromUnicodeScalar(key);
            int i = key & PageMask;

            if (failIfExists && page[i] != null)
                throw new ArgumentException(SR.Format(SR.CollectionDuplicateKey, key));

            page[i] = value;
            _count = 0;
        }

        internal CharacterMetrics GetValue(int key)
        {
            CharacterMetrics metrics = null;

            if (key >= 0 && key <= FontFamilyMap.LastUnicodeScalar && _pageTable != null)
            {
                CharacterMetrics[] page = _pageTable[key >> PageShift];
                if (page != null)
                    metrics = page[key & PageMask];
            }

            return metrics;
        }

View on GitHub (pinned to 81131a70a4)