Unity-Technologies/UnityCsReference · error · ArgumentException

Parameter selected must be of type System.Enum

Error message

Parameter selected must be of type System.Enum

What it means

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.

Source

Thrown at Editor/Mono/EditorGUI.cs:4179

        [AutoStaticsCleanupOnCodeReload]
        private static EnumData s_CurrentEnumData;

        private static bool CheckCurrentEnumTypeEnabled(int value)
        {
            return s_CurrentCheckEnumEnabled(s_CurrentEnumData.values[value]);
        }

        // Make an enum popup selection field.
        private static Enum EnumPopupInternal(Rect position, GUIContent label, Enum selected, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)
        {
            return EnumPopupInternal(position, label, selected, selected.GetType(), checkEnabled, includeObsolete, style);
        }

        private static Enum EnumPopupInternal(Rect position, GUIContent label, Enum selected, Type enumType, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Parameter selected must be of type System.Enum", nameof(selected));
            }

            var enumData = EnumDataUtility.GetCachedEnumData(enumType, !includeObsolete);
            var i = showMixedValue ? -1 : Array.IndexOf(enumData.values, selected);
            var options = EnumNamesCache.GetEnumTypeLocalizedGUIContents(enumType, enumData);

            s_CurrentCheckEnumEnabled = checkEnabled;
            s_CurrentEnumData = enumData;
            i = PopupInternal(position, label, i, options, checkEnabled == null ? (Func<int, bool>)null : CheckCurrentEnumTypeEnabled, style);
            s_CurrentCheckEnumEnabled = null;
            return (i < 0 || i >= enumData.flagValues.Length) ? selected : enumData.values[i];
        }

        private static int EnumPopupInternal(Rect position, GUIContent label, int flagValue, Type enumType, Func<Enum, bool> checkEnabled, bool includeObsolete, GUIStyle style)
        {
            if (!enumType.IsEnum)
            {
                throw new ArgumentException("Parameter selected must be of type System.Enum", nameof(enumType));

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Verify enumType.IsEnum (and optionally enumType.GetEnumUnderType() is supported) before calling the popup.
  2. Route through the public EnumPopup overload that takes the Enum value directly rather than constructing a Type.
  3. Add a generic constraint 'where T : struct, Enum' on helper methods so misuse is caught at compile time.

Example fix

// before
var t = typeof(MyClass); // not an enum
EnumPopupInternal(rect, label, (Enum)null, t, null, false, style);

// after
if (t.IsEnum)
    EnumPopupInternal(rect, label, (Enum)Enum.GetValues(t).GetValue(0), t, null, false, style);
Defensive patterns

Strategy: type-guard

Validate before calling

if (enumType == null || !enumType.IsEnum) { Debug.LogError($"{enumType} is not an enum; cannot show EnumPopup"); return selected; }

Type guard

static bool IsRenderableEnum(Type t) => t != null && t.IsEnum;

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/18ed4ad06c07f87d. Report an issue: GitHub.