LuckyPennySoftware/MediatR · error · ArgumentException

Error registering the generic type: {requestType.FullName}.

Error message

Error registering the generic type: {requestType.FullName}. One of the generic type parameter's count of types that can close exceeds the maximum length allowed ({MaxTypesClosing}).

What it means

Thrown by GenerateCombinations (depth 0) when any single generic parameter's candidate-closing list has more entries than MaxTypesClosing (default 100). Each parameter is closed against all concrete types that fit, so one parameter with >100 candidates is rejected to prevent combinatorial blow-up.

Source

Thrown at src/MediatR/Registration/ServiceRegistrar.cs:265

              
        var combinations = GenerateCombinations(requestType, typesThatCanCloseForEachParameter, 0, cancellationToken);

        return combinations.Select(types => requestGenericTypeDefinition.MakeGenericType(types.ToArray())).ToList();
    }

    // Method to generate combinations recursively
    public static List<List<Type>> GenerateCombinations(Type requestType, List<List<Type>> lists, int depth = 0, CancellationToken cancellationToken = default)
    {
        if (depth == 0)
        {
            // Initial checks
            if (MaxGenericTypeParameters > 0 && lists.Count > MaxGenericTypeParameters)
                throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The number of generic type parameters exceeds the maximum allowed ({MaxGenericTypeParameters}).");

            foreach (var list in lists)
            {
                if (MaxTypesClosing > 0 && list.Count > MaxTypesClosing)
                    throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. One of the generic type parameter's count of types that can close exceeds the maximum length allowed ({MaxTypesClosing}).");
            }

            // Calculate the total number of combinations
            long totalCombinations = 1;
            foreach (var list in lists)
            {
                totalCombinations *= list.Count;
                if (MaxGenericTypeParameters > 0 && totalCombinations > MaxGenericTypeRegistrations)
                    throw new ArgumentException($"Error registering the generic type: {requestType.FullName}. The total number of generic type registrations exceeds the maximum allowed ({MaxGenericTypeRegistrations}).");
            }
        }

        if (depth >= lists.Count)
            return new List<List<Type>> { new List<Type>() };
       
        cancellationToken.ThrowIfCancellationRequested();

        var currentList = lists[depth];

View on GitHub (pinned to 916ef1b3d6)

Solutions

  1. Raise the cap deliberately: cfg.MaxTypesClosing = 250; and verify registration time stays acceptable.
  2. Reduce the candidate count by narrowing which types implement the shared marker, or split marker implementations across assemblies and only scan the relevant one.
  3. Register the specific closed handlers explicitly instead of relying on open-generic auto-closing.

Example fix

// before
// 150 classes implement ICommonRequest in one scanned assembly
cfg.MaxTypesClosing = 100; // default

// after
cfg.MaxTypesClosing = 200;
// or register explicitly:
cfg.AddRequestHandler<MySpecificRequest, MySpecificHandler>();
Defensive patterns

Strategy: validation

Validate before calling

// Count candidate closers per parameter and warn before AddMediatR
foreach (var list in candidateLists)
    if (list.Count > cfg.MaxTypesClosing)
        Console.WriteLine($"Parameter has {list.Count} closers (cap {cfg.MaxTypesClosing})");

Try / catch

try { services.AddMediatR(cfg => { /* ... */ }); }
catch (ArgumentException ex) when (ex.Message.Contains("count of types that can close exceeds"))
{
    logger.LogError(ex, "A generic parameter has too many closers; raise MaxTypesClosing or narrow types");
    throw;
}

Prevention

When it happens

Trigger: An open generic handler parameter that more than 100 concrete types could close (e.g. an IRequestHandler<MyMarker,...> where MyMarker is implemented by 150 classes in scanned assemblies).

Common situations: Marker interfaces or base request types shared by a very large number of DTOs; scanning a big assembly where many types happen to satisfy the closing constraint; inheriting a common interface broadly across a domain model.

Related errors


AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13). Data as JSON: /api/errors/5a8f045476c9e2c2. Report an issue: GitHub.