bchavez/Bogus · error · ArgumentException

When calling Enum<T>() with no parameters T must be an enum.

Error message

When calling Enum<T>() with no parameters T must be an enum.

What it means

Thrown by Randomizer.Enum<T> when typeof(T).IsEnum() is false. Despite the generic constraint 'where T : struct, Enum' (which prevents most misuse), the runtime check guards against edge cases where T passes the constraint but IsEnum reports false. The method needs an enum to enumerate values.

Source

Thrown at Source/Bogus/Randomizer.cs:659

      if( min != null && min > str.Length )
      {
         var missingChars = min - str.Length;
         var fillerChars = this.Replace("".PadRight(missingChars.Value, '?'));
         return str + fillerChars;
      }
      return str;
   }

   /// <summary>
   /// Picks a random enum value in T:Enum.
   /// </summary>
   /// <typeparam name="T">Must be an Enum</typeparam>
   /// <param name="exclude">Exclude enum values from being returned</param>
   public T Enum<T>(params T[] exclude) where T : struct, Enum
   {
      var e = typeof(T);
      if( !e.IsEnum() )
         throw new ArgumentException("When calling Enum<T>() with no parameters T must be an enum.");

      var selection = System.Enum.GetNames(e);

      if( exclude.Any() )
      {
         var excluded = exclude.Select(ex => System.Enum.GetName(e, ex));
         selection = selection.Except(excluded).ToArray();
      }

      if( !selection.Any() )
      {
         throw new ArgumentException("There are no values after exclusion to choose from.");
      }

      var val = this.ArrayElement(selection);

      System.Enum.TryParse(val, out T picked);
      return picked;

View on GitHub (pinned to 6ece18c5c2)

Solutions

  1. Pass a real enum type as T, e.g. f.Random.Enum<MyEnum>().
  2. Upgrade Bogus so the compile-time 'where T : Enum' constraint catches misuse.
  3. If using reflection, verify typeof(T).IsEnum before invoking.

Example fix

// before
var v = f.Random.Enum<int>();
// after
var v = f.Random.Enum<MyEnum>();
Defensive patterns

Strategy: type-guard

Validate before calling

static T SafeEnum<T>(Bogus.Randomizer r) where T : struct, Enum {
    return r.Enum<T>();
}

Type guard

static bool IsEnumType<T>() => typeof(T).IsEnum;

Try / catch

try { return r.Enum<T>(); }
catch (ArgumentException ex) when (ex.Message.Contains("must be an enum")) {
    // switch to a real enum type
}

Prevention

When it happens

Trigger: Calling f.Random.Enum<int>() through reflection or dynamic generic construction that bypasses compile-time constraints; historically called before the Enum constraint existed.

Common situations: Older code targeting a Bogus version without the generic constraint; reflection-based generic instantiation.

Related errors


AI-assisted analysis of bchavez/Bogus@6ece18c5c2 (2026-08-13). Data as JSON: /api/errors/a270e933e0ba01f2. Report an issue: GitHub.