PrismLibrary/Prism · error · ArgumentNullException

ArgumentNullException(nameof(action))

Error message

ArgumentNullException(nameof(action))

What it means

EventSubscription<TPayload>.InvokeAction executes the subscription's Action synchronously. It throws ArgumentNullException when the action parameter is null, which protects the publish pipeline from executing a null callback.

Solutions

  1. Keep the subscriber alive or pass keepReferenceAlive:true to Subscribe
  2. Unsubscribe when the subscriber is disposed so dead subscriptions are removed
  3. If overriding InvokeAction, never call it with a null action

Example fix

// before
_event.Subscribe(Handler); // Handler in short-lived object, weak ref dies
// after
_event.Subscribe(Handler, keepReferenceAlive: true);
// or unsubscribe on dispose: _event.Unsubscribe(token);
Defensive patterns

Strategy: try-catch

Validate before calling

var strategy = subscription.GetExecutionStrategy();
if (strategy == null) return; // dead/collected subscription

Try / catch

try { strategy(); }
catch (ArgumentNullException ex) when (ex.ParamName == "action") { log.Warn("Subscription action no longer available (weak reference collected)"); _event.Unsubscribe(token); }

Prevention

When it happens

Trigger: GetExecutionStrategy resolving a strategy whose action comes from a DelegateReference whose Target was garbage collected (weak reference) or is null, then publishing the event; overriding InvokeAction and calling it with null.

Common situations: Weak (keepReferenceAlive:false) subscriptions where the subscriber was collected before publish, so the action can no longer be resolved.

Related errors


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

Appendix: source

Thrown at src/Prism.Events/EventSubscription.cs:79

            Action action = this.Action;
            if (action != null)
            {
                return arguments =>
                {
                    InvokeAction(action);
                };
            }
            return null;
        }

        /// <summary>
        /// Invokes the specified <see cref="System.Action{TPayload}"/> synchronously when not overridden.
        /// </summary>
        /// <param name="action">The action to execute.</param>
        /// <exception cref="ArgumentNullException">An <see cref="ArgumentNullException"/> is thrown if <paramref name="action"/> is null.</exception>
        protected virtual void InvokeAction(Action action)
        {
            if (action == null) throw new ArgumentNullException(nameof(action));

            action();
        }
    }

    /// <summary>
    /// Provides a way to retrieve a <see cref="Delegate"/> to execute an action depending
    /// on the value of a second filter predicate that returns true if the action should execute.
    /// </summary>
    /// <typeparam name="TPayload">The type to use for the generic <see cref="System.Action{TPayload}"/> and <see cref="Predicate{TPayload}"/> types.</typeparam>
    public class EventSubscription<TPayload> : IEventSubscription
    {
        private readonly IDelegateReference _actionReference;
        private readonly IDelegateReference _filterReference;

        ///<summary>
        /// Creates a new instance of <see cref="EventSubscription{TPayload}"/>.
        ///</summary>

View on GitHub (pinned to 358118cd64)