dotnet/wpf · error · ArgumentException

SR.Format(SR.CannotConvertType, key.GetType(), "int")

Error message

SR.Format(SR.CannotConvertType, key.GetType(), "int")

What it means

CharacterMetricsDictionary accepts only int keys (or hex strings, see the string branch). ConvertKey throws this ArgumentException when the key object is neither a string nor an int — its runtime type cannot be converted to the dictionary's int key type.

Solutions

  1. Pass the key as an int Unicode scalar value (e.g. (int)'A')
  2. If using the non-generic IDictionary, box an int, not a long/char
  3. Cast or convert the key to int before insertion

Example fix

// before
 IDictionary dict = dictionary;
 dict.Add('A', metrics);
// after
 dict.Add((int)'A', metrics);
Defensive patterns

Strategy: type-guard

Validate before calling

bool IsValidKey(object key) => key is int i && i >= 0 && i <= 0x10FFFF;

Type guard

bool IsConvertibleKey(object key) => key is int || key is string;

Try / catch

try { ((IDictionary)dict).Add(key, value); } catch (ArgumentException ex) { /* key was neither int nor hex string */ }

Prevention

When it happens

Trigger: Calling Add(object, object) or the IDictionary/IDictionary<TKey,TValue> members with a boxed key of any other type (long, char, byte, double, enum) via a non-generic reference, e.g. adding through IDictionary or in XAML with an unsupported key type.

Common situations: Using the non-generic IDictionary interface where keys come from untyped data (deserialization, databinding); boxing a char key like 'A' expecting it to be its code point.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

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

        {
            ArgumentNullException.ThrowIfNull(key);

            int value;

            string s = key as string;
            if (s != null)
            {
                int i = 0;
                if (!FontFamilyMap.ParseHexNumber(s, ref i, out value) || i < s.Length)
                    throw new ArgumentException(SR.Format(SR.CannotConvertStringToType, s, "int"), nameof(key));
            }
            else if (key is int)
            {
                value = (int)key;
            }
            else
            {
                throw new ArgumentException(SR.Format(SR.CannotConvertType, key.GetType(), "int"), nameof(key));
            }

            if (value < 0 || value > FontFamilyMap.LastUnicodeScalar)
                throw new ArgumentException(SR.Format(SR.CodePointOutOfRange, value), nameof(key));

            return value;
        }

        private CharacterMetrics ConvertValue(object value)
        {
            CharacterMetrics metrics = value as CharacterMetrics;
            if (metrics != null)
                return metrics;

            ArgumentNullException.ThrowIfNull(value);

            throw new ArgumentException(SR.Format(SR.CannotConvertType, typeof(CharacterMetrics), value.GetType()));
        }

View on GitHub (pinned to 81131a70a4)