Unity-Technologies/UnityCsReference · error · ArgumentException
Specified enumType must be System.Enum
Error message
Specified enumType must be System.Enum
What it means
Thrown by the int-flag overload of EnumFlagsField when enumType.IsEnum is false. Unlike 184, this overload legitimately accepts an int value plus a Type, so the guard is the primary defense: callers supply a Type, and if it is not an enum the method refuses. The message correctly names 'enumType'.
Source
Thrown at Editor/Mono/EditorGUI.cs:4686
throw new NotSupportedException(string.Format("Unsupported enum base type for {0}", enumType.Name));
var id = GUIUtility.GetControlID(s_EnumFlagsField, FocusType.Keyboard, position);
position = PrefixLabel(position, id, label);
var flagsInt = EnumDataUtility.EnumFlagsToInt(enumData, enumValue);
BeginChangeCheck();
flagsInt = MaskFieldGUI.DoMaskField(position, id, flagsInt, enumData.displayNames, enumData.flagValues, style, out changedFlags, out changedToValue);
if (!EndChangeCheck())
return enumValue;
return EnumDataUtility.IntToEnumFlags(enumType, flagsInt);
}
internal static int EnumFlagsField(Rect position, GUIContent label, int enumValue, Type enumType, bool includeObsolete, GUIStyle style)
{
if (!enumType.IsEnum)
throw new ArgumentException("Specified enumType must be System.Enum", nameof(enumType));
var enumData = EnumDataUtility.GetCachedEnumData(enumType, !includeObsolete);
if (!enumData.serializable)
// this is the same message used in SerializedPropertyEnumHelper.cpp
throw new NotSupportedException(string.Format("Unsupported enum base type for {0}", enumType.Name));
var id = GUIUtility.GetControlID(s_EnumFlagsField, FocusType.Keyboard, position);
position = PrefixLabel(position, id, label);
int changedFlags;
bool changedToValue;
return MaskFieldGUI.DoMaskField(position, id, enumValue, enumData.displayNames, enumData.flagValues, style, out changedFlags, out changedToValue, enumType.GetEnumUnderlyingType());
}
public static void ObjectField(Rect position, SerializedProperty property)
{
ObjectField(position, property, null, null, EditorStyles.objectField);
}View on GitHub (pinned to 225b0fbdb5)
Solutions
- Guard with if (!type.IsEnum) before calling the int overload.
- Switch to the Enum-typed overload so the Type is always derived from a real enum value.
- Fix the registry/config to reference the actual enum type, not its underlying type.
Example fix
// before EnumFlagsField(rect, label, flags, typeof(int), false, style); // after EnumFlagsField(rect, label, flags, typeof(MyFlagsEnum), false, style);
Defensive patterns
Strategy: type-guard
Validate before calling
if (enumType == null || !enumType.IsEnum) { Debug.LogError($"{enumType} is not an enum"); return enumValue; } Type guard
static bool IsEnumType(Type t) => t != null && t.IsEnum;
Prevention
- Pass the actual enum Type (not its underlying integral type) to the int-flag EnumFlagsField.
- Validate Type registry entries with IsEnum before invoking.
- Prefer the Enum-typed overload where possible.
When it happens
Trigger: Calling EnumFlagsField(rect, label, someInt, someType, ...) where someType is typeof(int), typeof(string), or any non-enum. This is the realistic hit because the int overload is explicitly Type-driven.
Common situations: Generic bitfield editor utilities that store flags as int and pass a Type from a runtime registry; migrated code where the Type argument was left as the underlying integral type.
Related errors
- Parameter enumValue must be of type System.Enum
- Parameter selected must be of type System.Enum
- Unsupported enum base type for {0}
- ${renderPipelineType} must be a valid ${RenderPipeline}
- The DialogOptOut type named {0} has not been implemented.
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/529af9b89e57aa5a.
Report an issue: GitHub.