PrismLibrary/Prism · error · ArgumentNullException

ArgumentNullException(nameof(eventSubscription))

Error message

ArgumentNullException(nameof(eventSubscription))

What it means

EventBase.InternalSubscribe adds an IEventSubscription to the event's subscription list and assigns it a token. It throws ArgumentNullException when the supplied eventSubscription is null because a null subscription cannot be tracked or later unsubscribed.

Solutions

  1. Ensure the subscription object is fully constructed before calling InternalSubscribe
  2. Check factory results for null before subscribing
  3. If overriding, add your own null guard and fail early with a clear message

Example fix

// before
var sub = BuildSubscription(); // may return null
InternalSubscribe(sub);
// after
var sub = BuildSubscription() ?? throw new InvalidOperationException("subscription factory returned null");
InternalSubscribe(sub);
Defensive patterns

Strategy: type-guard

Validate before calling

if (subscription == null) throw new InvalidOperationException("Subscription factory returned null");

Type guard

bool CanSubscribe(IEventSubscription s) => s != null;

Try / catch

try { InternalSubscribe(sub); }
catch (ArgumentNullException ex) when (ex.ParamName == "eventSubscription") { log.Error("Null subscription passed to InternalSubscribe"); }

Prevention

When it happens

Trigger: Overriding PubSubEvent/EventBase and calling InternalSubscribe(null), or custom IEventSubscription factories returning null which is then passed straight to InternalSubscribe.

Common situations: Custom event subclasses in Prism where the execution-strategy/subscription construction was refactored and now returns null; test doubles of EventBase.

Related errors


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

Appendix: source

Thrown at src/Prism.Events/EventBase.cs:39

        /// Gets the list of current subscriptions.
        /// </summary>
        /// <value>The current subscribers.</value>
        protected ICollection<IEventSubscription> Subscriptions
        {
            get { return _subscriptions; }
        }

        /// <summary>
        /// Adds the specified <see cref="IEventSubscription"/> to the subscribers' collection.
        /// </summary>
        /// <param name="eventSubscription">The subscriber.</param>
        /// <returns>The <see cref="SubscriptionToken"/> that uniquely identifies every subscriber.</returns>
        /// <remarks>
        /// Adds the subscription to the internal list and assigns it a new <see cref="SubscriptionToken"/>.
        /// </remarks>
        protected virtual SubscriptionToken InternalSubscribe(IEventSubscription eventSubscription)
        {
            if (eventSubscription == null) throw new ArgumentNullException(nameof(eventSubscription));

            eventSubscription.SubscriptionToken = new SubscriptionToken(Unsubscribe);

            lock (Subscriptions)
            {
                Subscriptions.Add(eventSubscription);
            }
            return eventSubscription.SubscriptionToken;
        }

        /// <summary>
        /// Calls all the execution strategies exposed by the list of <see cref="IEventSubscription"/>.
        /// </summary>
        /// <param name="arguments">The arguments that will be passed to the listeners.</param>
        /// <remarks>Before executing the strategies, this class will prune all the subscribers from the
        /// list that return a <see langword="null" /> <see cref="Action{T}"/> when calling the
        /// <see cref="IEventSubscription.GetExecutionStrategy"/> method.</remarks>
        protected virtual void InternalPublish(params object[] arguments)

View on GitHub (pinned to 358118cd64)