LuckyPennySoftware/MediatR · error · ArgumentException

{requestType.Name} does not implement IStreamRequest<TRespon

Error message

{requestType.Name} does not implement IStreamRequest<TResponse>

What it means

The non-generic CreateStream(object) overload reflects over the object's interfaces looking for IStreamRequest<>. If none is found, the object is not a stream request, so ArgumentException is thrown naming the type and the missing IStreamRequest<TResponse> contract.

Source

Thrown at src/MediatR/Mediator.cs:195

        var items = streamHandler.Handle(request, _serviceProvider, cancellationToken);

        return items;
    }


    public IAsyncEnumerable<object?> CreateStream(object request, CancellationToken cancellationToken = default)
    {
        if (request == null)
        {
            throw new ArgumentNullException(nameof(request));
        }

        var handler = _streamRequestHandlers.GetOrAdd(request.GetType(), static requestType =>
        {
            var requestInterfaceType = requestType.GetInterfaces().FirstOrDefault(static i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IStreamRequest<>));
            if (requestInterfaceType is null)
            {
                throw new ArgumentException($"{requestType.Name} does not implement IStreamRequest<TResponse>", nameof(request));
            }

            var responseType = requestInterfaceType.GetGenericArguments()[0];
            var wrapperType = typeof(StreamRequestHandlerWrapperImpl<,>).MakeGenericType(requestType, responseType);
            var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {requestType}");
            return (StreamRequestHandlerBase)wrapper;
        });

        var items = handler.Handle(request, _serviceProvider, cancellationToken);

        return items;
    }
}

View on GitHub (pinned to 916ef1b3d6)

Solutions

  1. Mark the type `public record StreamX : IStreamRequest<Y>` and call CreateStream.
  2. If the payload is a normal request, call Send, not CreateStream.
  3. Prefer the generic CreateStream<TResponse>(IStreamRequest<TResponse>) overload to get compile-time checking.

Example fix

// before
public record Poll(int Id) : IRequest<int>;
mediator.CreateStream((object)new Poll(1)); // ArgumentException
// after
public record Poll(int Id) : IStreamRequest<int>;
mediator.CreateStream(new Poll(1));
Defensive patterns

Strategy: type-guard

Validate before calling

var isStream = request.GetType().GetInterfaces()
    .Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IStreamRequest<>));
if (!isStream) throw new ArgumentException($"{request.GetType().Name} is not an IStreamRequest<T>.", nameof(request));

Type guard

static bool IsStreamRequest(object o) =>
    o.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IStreamRequest<>));

Prevention

When it happens

Trigger: Calling mediator.CreateStream(someObject) where someObject implements IRequest<> (a normal request) or nothing — anything other than IStreamRequest<TResponse>.

Common situations: Dispatching through a non-generic boundary (messaging, reflection) and passing a normal IRequest instead of IStreamRequest; forgetting to mark a query as a stream request; confusing Send and CreateStream.

Related errors


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