LuckyPennySoftware/MediatR · error · ArgumentException
notification does not implement $INotification
Error message
notification does not implement $INotification
What it means
The non-generic Publish(object) overload pattern-matches the payload: nulls throw ArgumentNullException, INotification instances are forwarded, and anything else throws ArgumentException. Note the message text itself contains a literal bug — the source reads `$"{nameof(notification)} does not implement ${nameof(INotification)}"`, so the rendered text is `notification does not implement $INotification` (a stray `$` before the interface name).
Source
Thrown at src/MediatR/Mediator.cs:137
}
public Task Publish<TNotification>(TNotification notification, CancellationToken cancellationToken = default)
where TNotification : INotification
{
if (notification == null)
{
throw new ArgumentNullException(nameof(notification));
}
return PublishNotification(notification, cancellationToken);
}
public Task Publish(object notification, CancellationToken cancellationToken = default) =>
notification switch
{
null => throw new ArgumentNullException(nameof(notification)),
INotification instance => PublishNotification(instance, cancellationToken),
_ => throw new ArgumentException($"{nameof(notification)} does not implement ${nameof(INotification)}")
};
/// <summary>
/// Override in a derived class to control how the tasks are awaited. By default the implementation calls the <see cref="INotificationPublisher"/>.
/// </summary>
/// <param name="handlerExecutors">Enumerable of tasks representing invoking each notification handler</param>
/// <param name="notification">The notification being published</param>
/// <param name="cancellationToken">The cancellation token</param>
/// <returns>A task representing invoking all handlers</returns>
protected virtual Task PublishCore(IEnumerable<NotificationHandlerExecutor> handlerExecutors, INotification notification, CancellationToken cancellationToken)
=> _publisher.Publish(handlerExecutors, notification, cancellationToken);
private Task PublishNotification(INotification notification, CancellationToken cancellationToken = default)
{
var handler = _notificationHandlers.GetOrAdd(notification.GetType(), static notificationType =>
{
var wrapperType = typeof(NotificationHandlerWrapperImpl<>).MakeGenericType(notificationType);
var wrapper = Activator.CreateInstance(wrapperType) ?? throw new InvalidOperationException($"Could not create wrapper for type {notificationType}");
View on GitHub (pinned to 916ef1b3d6)
Solutions
- Make the type implement INotification: `public record FooHappened : INotification`.
- If the payload is actually a request, call Send instead of Publish.
- Use the generic Publish<TNotification> overload where TNotification : INotification to catch mismatches at compile time.
Example fix
// before
public class OrderShipped { public Guid Id; }
mediator.Publish(orderShipped); // ArgumentException
// after
public record OrderShipped(Guid Id) : INotification;
mediator.Publish(orderShipped); Defensive patterns
Strategy: type-guard
Validate before calling
if (notification is not INotification)
throw new ArgumentException($"{notification?.GetType().Name ?? "null"} is not an INotification.", nameof(notification)); Type guard
static bool IsNotification(object o) => o is INotification;
Prevention
- Use the generic Publish<TNotification>() where TNotification : INotification overload.
- Mark event types with INotification at definition.
- Do not pass request objects to Publish.
When it happens
Trigger: Calling mediator.Publish(someObject) where someObject does not implement INotification (e.g. a plain DTO, an event from another library, or a request mistakenly sent as a notification).
Common situations: Cross-system dispatch that boxes payloads as object and passes the wrong type; reusing a request type as a notification without implementing INotification; legacy payloads not yet migrated to the notification contract.
Related errors
- {requestType.Name} does not implement IRequest
- Could not create wrapper for type {notificationType}
- {requestType.Name} does not implement IStreamRequest<TRespon
- The type "{openBehaviorType.Name}" must implement IPipelineB
- Could not create wrapper type for {requestType}
AI-assisted analysis of LuckyPennySoftware/MediatR@916ef1b3d6 (2026-08-13).
Data as JSON: /api/errors/7a369a91d7839b8a.
Report an issue: GitHub.