{"record":{"id":"9b7c01361c000c70","repo":"dotnet/wpf","slug":"invalidenumargumentexception-nameof-value-int-modifiers","errorCode":null,"errorMessage":"InvalidEnumArgumentException(nameof(value), (int)modifiers, typeof(ModifierKeys))","messagePattern":"InvalidEnumArgumentException\\(nameof\\(value\\), \\(int\\)modifiers, typeof\\(ModifierKeys\\)\\)","errorType":"exception","errorClass":"InvalidEnumArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Input/ModifierKeysConverter.cs","lineNumber":109,"sourceCode":"        /// Converts a <paramref name=\"value\"/> of <see cref=\"ModifierKeys\"/> to its <see langword=\"string\"/> represensation.\n        /// </summary>\n        /// <param name=\"context\">Serialization Context</param>\n        /// <param name=\"culture\">Culture Info</param>\n        /// <param name=\"value\">ModifierKeys value</param>\n        /// <param name=\"destinationType\">Type to Convert</param>\n        /// <returns>A <see langword=\"string\"/> representing the <see cref=\"ModifierKeys\"/> specified by <paramref name=\"value\"/>.</returns>\n        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)\n        {\n            ArgumentNullException.ThrowIfNull(destinationType);\n\n            // We can only convert to string\n            if (destinationType != typeof(string))\n                throw GetConvertToException(value, destinationType);\n\n            // Check whether value falls within defined set\n            ModifierKeys modifiers = (ModifierKeys)value;\n            if (!IsDefinedModifierKeys(modifiers))\n                throw new InvalidEnumArgumentException(nameof(value), (int)modifiers, typeof(ModifierKeys));\n\n            // This is a fast path for when only a single modifier (or none) is set, which is a very common scenario.\n            // Therefore we want a fast path with an allocation free return, taking advantage of interned strings.\n            return modifiers switch\n            {\n                ModifierKeys.None => string.Empty,\n                ModifierKeys.Control => \"Ctrl\",\n                ModifierKeys.Alt => \"Alt\",\n                ModifierKeys.Shift => \"Shift\",\n                ModifierKeys.Windows => \"Windows\",\n                // Since we were not able to match a single modifier alone, there must be multiple modifiers involved.\n                _ => ConvertMultipleModifiers(modifiers),\n            };\n        }\n\n        private static string ConvertMultipleModifiers(ModifierKeys modifiers)\n        {\n            // Ctrl+Alt+Windows+Shift is the maximum char length, though the composition of such value is improbable","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Input/ModifierKeysConverter.cs#L91-L127","documentation":"ModifierKeysConverter.ConvertTo converts a ModifierKeys value to its string representation (e.g. 'Control+Alt'). Before converting it verifies the value is one of the defined ModifierKeys enum values; if the boxed value is not a valid ModifierKeys, an InvalidEnumArgumentException is thrown. This guards the converter against foreign or out-of-range values passed to the type conversion pipeline.","triggerScenarios":"Calling ConvertTo with a value that is not a ModifierKeys enum value, a value cast from an arbitrary int that falls outside the defined ModifierKeys set (e.g. (ModifierKeys)999), or a destinationType other than string (that path throws GetConvertToException first).","commonSituations":"Data binding or XAML serialization pipelines feeding user-supplied integers into the converter; deserializing old/persisted settings where the stored int no longer maps to a ModifierKeys member after enum changes.","solutions":["Validate the value is a defined ModifierKeys member before calling ConvertTo (e.g. Enum.IsDefined(typeof(ModifierKeys), value)).","Ensure the object passed in is actually a ModifierKeys instance, not a raw int or another enum.","Check the destinationType parameter is typeof(string).","Catch InvalidEnumArgumentException at the conversion boundary and substitute ModifierKeys.None or a fallback rendering."],"exampleFix":"// before\nvar text = converter.ConvertTo(keyValue, typeof(string)); // keyValue may be (ModifierKeys)999\n// after\nif (Enum.IsDefined(typeof(ModifierKeys), keyValue))\n    text = converter.ConvertTo(keyValue, typeof(string));\nelse\n    text = converter.ConvertTo(ModifierKeys.None, typeof(string));","handlingStrategy":"validation","validationCode":"bool canConvert = value is ModifierKeys mk && Enum.IsDefined(typeof(ModifierKeys), mk) && destinationType == typeof(string);","typeGuard":"static bool IsValidModifierKeys(object v) => v is ModifierKeys mk && Enum.IsDefined(typeof(ModifierKeys), mk);","tryCatchPattern":"try { return converter.ConvertTo(value, typeof(string)); }\ncatch (InvalidEnumArgumentException) { return string.Empty; }","preventionTips":["Only pass ModifierKeys instances into the converter.","Check Enum.IsDefined before any enum-to-string conversion.","Validate destinationType is typeof(string) beforehand."],"tags":["wpf","enum","type-conversion"],"backgroundTag":"invalid-enum-value","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"}