PrismLibrary/Prism · error · ArgumentNullException

ArgumentNullException("delegate")

Error message

ArgumentNullException("delegate")

What it means

DelegateReference wraps a delegate as a strong or weak reference for Prism's event aggregator. Passing a null Delegate to the constructor throws ArgumentNullException with the literal name "delegate". A non-null delegate is mandatory because the reference has nothing to wrap otherwise.

Solutions

  1. Pass a non-null delegate to DelegateReference / Subscribe
  2. Check the delegate variable for null before subscribing
  3. Use nameof-safe subscription with a concrete method group instead of a nullable delegate field

Example fix

// before
Action<MyPayload> handler = _handler; // may be null
_event.Subscribe(handler);
// after
if (_handler != null) _event.Subscribe(_handler);
Defensive patterns

Strategy: validation

Validate before calling

if (handler == null) throw new InvalidOperationException("Cannot subscribe with a null delegate");
_event.Subscribe(handler);

Type guard

bool IsSubscribable(Delegate d) => d != null;

Try / catch

try { _event.Subscribe(handler); }
catch (ArgumentNullException) { log.Error("Subscribe called with null delegate"); }

Prevention

When it happens

Trigger: Calling new DelegateReference(null, keepReferenceAlive) directly, or via PubSubEvent.Subscribe(null, ...) / filter/action delegates resolved to null at runtime (e.g. a delegate field that is null).

Common situations: Subscribing to an EventAggregator event with an uninitialized method-group or Func field; passing result of a factory method that returned null; older Prism versions where the parameter is named "delegate" so the exception message shows "delegate" instead of @delegate.

Related errors


AI-assisted analysis of PrismLibrary/Prism@358118cd64 (2026-09-15). Data as JSON: /api/errors/0fdee5e9ba14aaae. Report an issue: GitHub.

Appendix: source

Thrown at src/Prism.Events/DelegateReference.cs:30

    /// internally by the Prism Library.
    /// </summary>
    public class DelegateReference : IDelegateReference
    {
        private readonly Delegate _delegate;
        private readonly WeakReference _weakReference;
        private readonly MethodInfo _method;
        private readonly Type _delegateType;

        /// <summary>
        /// Initializes a new instance of <see cref="DelegateReference"/>.
        /// </summary>
        /// <param name="delegate">The original <see cref="Delegate"/> to create a reference for.</param>
        /// <param name="keepReferenceAlive">If <see langword="false" /> the class will create a weak reference to the delegate, allowing it to be garbage collected. Otherwise it will keep a strong reference to the target.</param>
        /// <exception cref="ArgumentNullException">If the passed <paramref name="delegate"/> is not assignable to <see cref="Delegate"/>.</exception>
        public DelegateReference(Delegate @delegate, bool keepReferenceAlive)
        {
            if (@delegate == null)
                throw new ArgumentNullException("delegate");

            if (keepReferenceAlive)
            {
                this._delegate = @delegate;
            }
            else
            {
                _weakReference = new WeakReference(@delegate.Target);
                _method = @delegate.GetMethodInfo();
                _delegateType = @delegate.GetType();
            }
        }

        /// <summary>
        /// Gets the <see cref="Delegate" /> (the target) referenced by the current <see cref="DelegateReference"/> object.
        /// </summary>
        /// <value><see langword="null"/> if the object referenced by the current <see cref="DelegateReference"/> object has been garbage collected; otherwise, a reference to the <see cref="Delegate"/> referenced by the current <see cref="DelegateReference"/> object.</value>
        public Delegate Target

View on GitHub (pinned to 358118cd64)