dotnet/reactive · error · ArgumentNullException

source

Error message

source

What it means

ObserveOnDispatcher(source, priority) throws ArgumentNullException when the source sequence is null. The method builds a CoreDispatcherScheduler from CoreDispatcherScheduler.Current.Dispatcher with the given priority and passes the source to Synchronization.ObserveOn; it rejects a null source up front. This follows Rx's convention of eagerly validating arguments so failures point at the calling code.

Solutions

  1. Make the producer return Observable.Empty<T>() or Observable.Throw<T>(ex) instead of null.
  2. Guard the chain with a null check before applying ObserveOnDispatcher.
  3. Initialize the observable field eagerly (constructor or field initializer) so it is never null when the pipeline is built.
  4. Prefer ObserveOnCoreDispatcher() when no custom priority is needed — the validation behavior is identical but the API is simpler.

Example fix

// before
IObservable<EventData> stream = _events; // null until Init()
stream.ObserveOnDispatcher(CoreDispatcherPriority.High).Subscribe(...);
// after
if (stream == null) stream = Observable.Empty<EventData>();
stream.ObserveOnDispatcher(CoreDispatcherPriority.High).Subscribe(...);
Defensive patterns

Strategy: validation

Validate before calling

if (source == null) throw new InvalidOperationException("source sequence not initialized");
source.ObserveOnDispatcher(CoreDispatcherPriority.Normal).Subscribe(handler);

Type guard

bool IsSubscribable<T>(IObservable<T> s) => s != null;

Try / catch

try { source.ObserveOnDispatcher(priority).Subscribe(handler); }
catch (ArgumentNullException ex) when (ex.ParamName == "source")
{ logger.LogWarning("Observable pipeline skipped: source was null"); }

Prevention

When it happens

Trigger: Invoking the extension on a null IObservable<T>, typically because an upstream factory/property returned null or a conditionally-built chain assigned null to the sequence variable.

Common situations: View-models exposing IObservable properties that are null until initialization completes; service locators returning null instead of throwing; fluent chains assembled from nullable data sources.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/8c69403110c21a96. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/CoreDispatcherObservable.cs:147

                throw new ArgumentNullException(nameof(source));
            }

            return Synchronization.ObserveOn(source, CoreDispatcherScheduler.Current);
        }

        /// <summary>
        /// Wraps the source sequence in order to run its observer callbacks on the dispatcher associated with the current window.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="priority">Priority to schedule work items at.</param>
        /// <returns>The source sequence whose observations happen on the current window's dispatcher.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> is null.</exception>
        public static IObservable<TSource> ObserveOnDispatcher<TSource>(this IObservable<TSource> source, CoreDispatcherPriority priority)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return Synchronization.ObserveOn(source, new CoreDispatcherScheduler(CoreDispatcherScheduler.Current.Dispatcher, priority));
        }

        #endregion

        #region SubscribeOn[CoreDispatcher]

        /// <summary>
        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the specified dispatcher.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="dispatcher">Dispatcher whose associated message loop is used to perform subscription and unsubscription actions on.</param>
        /// <returns>The source sequence whose subscriptions and unsubscriptions happen on the specified dispatcher.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="dispatcher"/> is null.</exception>
        /// <remarks>

View on GitHub (pinned to 94b5d5ab91)