{"record":{"id":"4d4d14a2d32de29e","repo":"JamesNK/Newtonsoft.Json","slug":"type-provided-must-be-an-enum","errorCode":null,"errorMessage":"Type provided must be an Enum.","messagePattern":"Type provided must be an Enum\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Utilities/EnumUtils.cs","lineNumber":266,"sourceCode":"                    return (ulong)(int)value;\n                case PrimitiveTypeCode.UInt64:\n                    return (ulong)value;\n                case PrimitiveTypeCode.Int64:\n                    return (ulong)(long)value;\n                // All unsigned types will be directly cast\n                default:\n                    throw new InvalidOperationException(\"Unknown enum type.\");\n            }\n        }\n\n        public static object ParseEnum(Type enumType, NamingStrategy? namingStrategy, string value, bool disallowNumber)\n        {\n            ValidationUtils.ArgumentNotNull(enumType, nameof(enumType));\n            ValidationUtils.ArgumentNotNull(value, nameof(value));\n\n            if (!enumType.IsEnum())\n            {\n                throw new ArgumentException(\"Type provided must be an Enum.\", nameof(enumType));\n            }\n\n            EnumInfo entry = ValuesAndNamesPerEnum.Get(new StructMultiKey<Type, NamingStrategy?>(enumType, namingStrategy));\n            string[] enumNames = entry.Names;\n            string[] resolvedNames = entry.ResolvedNames;\n            ulong[] enumValues = entry.Values;\n\n            // first check if the entire text (including commas) matches a resolved name\n            int? matchingIndex = FindIndexByName(resolvedNames, value, 0, value.Length, StringComparison.Ordinal);\n            if (matchingIndex != null)\n            {\n                return Enum.ToObject(enumType, enumValues[matchingIndex.Value]);\n            }\n\n            int firstNonWhitespaceIndex = -1;\n            for (int i = 0; i < value.Length; i++)\n            {\n                if (!char.IsWhiteSpace(value[i]))","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Utilities/EnumUtils.cs#L248-L284","documentation":"ParseEnum (EnumUtils.cs:259-381) requires enumType to actually be an enum. It checks enumType.IsEnum() at EnumUtils.cs:264-267 and throws ArgumentException if the type is a class/struct/interface/primitive — only true enum types carry the member/value mapping ParseEnum relies on.","triggerScenarios":"Passing a non-enum Type to ParseEnum — typeof(int), typeof(string), typeof(MyClass), or an open generic — typically from reflection/generic code that has lost the enum constraint.","commonSituations":"Generic deserialization helpers that accept arbitrary Type parameters; misconfigured converters that pass the wrong type; dynamically resolved types that unexpectedly resolve to a non-enum.","solutions":["Guard with type.IsEnum before calling ParseEnum.","Constrain generic methods with `where T : struct, Enum` (or `where TEnum : struct, IComparable, IFormattable, IConvertible` on older runtimes).","Resolve and verify the concrete enum type before invoking.","Return an error/default rather than calling ParseEnum on non-enum types."],"exampleFix":"// before\nobject Parse<T>(string s) => EnumUtils.ParseEnum(typeof(T), null, s, false); // T may be non-enum\n// after\nobject Parse<T>(string s) {\n    if (!typeof(T).IsEnum) throw new InvalidOperationException($\"{typeof(T)} is not an enum.\");\n    return EnumUtils.ParseEnum(typeof(T), null, s, false);\n}","handlingStrategy":"type-guard","validationCode":"// Guard before calling ParseEnum.\nif (!enumType.IsEnum) throw new ArgumentException($\"{enumType} is not an enum.\");","typeGuard":"static bool IsEnumType(Type t) => t.IsEnum;","tryCatchPattern":"try { return EnumUtils.ParseEnum(enumType, null, value, false); } catch (ArgumentException ex) when (ex.Message.Contains(\"must be an Enum\")) { /* caller passed wrong type */ }","preventionTips":["Constrain generic methods with `where T : struct, Enum`.","Check type.IsEnum before invoking reflection-based enum APIs.","Resolve and verify the concrete enum type at the boundary."],"tags":["enum","reflection","newtonsoft-json"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}