{"record":{"id":"18ed4ad06c07f87d","repo":"Unity-Technologies/UnityCsReference","slug":"parameter-selected-must-be-of-type-system-enum","errorCode":null,"errorMessage":"Parameter selected must be of type System.Enum","messagePattern":"Parameter selected must be of type System\\.Enum","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/EditorGUI.cs","lineNumber":4179,"sourceCode":"        [AutoStaticsCleanupOnCodeReload]\n        private static EnumData s_CurrentEnumData;\n\n        private static bool CheckCurrentEnumTypeEnabled(int value)\n        {\n            return s_CurrentCheckEnumEnabled(s_CurrentEnumData.values[value]);\n        }\n\n        // Make an enum popup selection field.\n        private static Enum EnumPopupInternal(Rect position, GUIContent label, Enum selected, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)\n        {\n            return EnumPopupInternal(position, label, selected, selected.GetType(), checkEnabled, includeObsolete, style);\n        }\n\n        private static Enum EnumPopupInternal(Rect position, GUIContent label, Enum selected, Type enumType, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)\n        {\n            if (!enumType.IsEnum)\n            {\n                throw new ArgumentException(\"Parameter selected must be of type System.Enum\", nameof(selected));\n            }\n\n            var enumData = EnumDataUtility.GetCachedEnumData(enumType, !includeObsolete);\n            var i = showMixedValue ? -1 : Array.IndexOf(enumData.values, selected);\n            var options = EnumNamesCache.GetEnumTypeLocalizedGUIContents(enumType, enumData);\n\n            s_CurrentCheckEnumEnabled = checkEnabled;\n            s_CurrentEnumData = enumData;\n            i = PopupInternal(position, label, i, options, checkEnabled == null ? (Func<int, bool>)null : CheckCurrentEnumTypeEnabled, style);\n            s_CurrentCheckEnumEnabled = null;\n            return (i < 0 || i >= enumData.flagValues.Length) ? selected : enumData.values[i];\n        }\n\n        private static int EnumPopupInternal(Rect position, GUIContent label, int flagValue, Type enumType, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)\n        {\n            if (!enumType.IsEnum)\n            {\n                throw new ArgumentException(\"Parameter selected must be of type System.Enum\", nameof(enumType));","sourceCodeStart":4161,"sourceCodeEnd":4197,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/EditorGUI.cs#L4161-L4197","documentation":"Thrown by the type-explicit overload of EnumPopupInternal when enumType.IsEnum is false. The Enum-overload delegates by calling selected.GetType(), so in normal typed usage this guard is effectively unreachable; it exists for callers that supply a Type explicitly (the int-flag and explicit-Type overloads). The message blames the 'selected' parameter for historical continuity.","triggerScenarios":"Direct internal invocation of EnumPopupInternal with an explicit Type argument that is not an enum (e.g. typeof(int), typeof(string), or a class type). Reaching it through the public EnumPopup is only possible if reflection or a bad generic passes a non-enum Type.","commonSituations":"Reflection-based editor tooling that builds a popup from a runtime Type without first checking IsEnum; wrapping EditorGUI.EnumPopup in a generic helper that loses the enum constraint.","solutions":["Verify enumType.IsEnum (and optionally enumType.GetEnumUnderType() is supported) before calling the popup.","Route through the public EnumPopup overload that takes the Enum value directly rather than constructing a Type.","Add a generic constraint 'where T : struct, Enum' on helper methods so misuse is caught at compile time."],"exampleFix":"// before\nvar t = typeof(MyClass); // not an enum\nEnumPopupInternal(rect, label, (Enum)null, t, null, false, style);\n\n// after\nif (t.IsEnum)\n    EnumPopupInternal(rect, label, (Enum)Enum.GetValues(t).GetValue(0), t, null, false, style);","handlingStrategy":"type-guard","validationCode":"if (enumType == null || !enumType.IsEnum) { Debug.LogError($\"{enumType} is not an enum; cannot show EnumPopup\"); return selected; }","typeGuard":"static bool IsRenderableEnum(Type t) => t != null && t.IsEnum;","tryCatchPattern":null,"preventionTips":["Prefer the Enum-typed EnumPopup overload so the Type is derived from the value.","Constrain generic editor helpers with 'where T : struct, Enum'.","Validate any Type[] registry before feeding entries into popup APIs."],"tags":["csharp","unity-editor","enum","gui","popup"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}