dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'source')

Error message

Value cannot be null. (Parameter 'source')

What it means

ControlObservable.SubscribeOn throws ArgumentNullException when the source IObservable<TSource> is null. Extension methods on IObservable validate the receiver explicitly because a null 'this' does not throw on its own in C# extension-method calls. The scheduler-based subscribe redirection must not be built around a null sequence.

Solutions

  1. Ensure the source observable is non-null before calling SubscribeOn.
  2. If the source may be absent, guard with a null check or use Observable.Empty<TSource>() instead of null.
  3. Fix the upstream factory/property so it never returns a null IObservable.

Example fix

// before
IObservable<Data> src = GetSource(); // returns null
src.SubscribeOn(this.tabControl1).Subscribe(...);
// after
IObservable<Data> src = GetSource() ?? Observable.Empty<Data>();
src.SubscribeOn(this.tabControl1).Subscribe(...);
Defensive patterns

Strategy: validation

Validate before calling

if (source is null) throw new InvalidOperationException("source observable is null");
source.SubscribeOn(control);

Type guard

bool HasSource<TSource>(IObservable<TSource> s) => s is not null;

Try / catch

try { source.SubscribeOn(control).Subscribe(obs); } catch (ArgumentNullException ex) when (ex.ParamName == "source") { Log("Source observable was null"); }

Prevention

When it happens

Trigger: Calling nullObservable.SubscribeOn(someControl) — typically when the observable came from a factory, service, or property that returned null.

Common situations: Chained Rx queries where an earlier operator or a lazy provider produced null instead of an empty/throwing sequence; dependency injection returning null for an observable service.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive.Windows.Forms/System.Reactive.Linq/ControlObservable.cs:35

    public static class ControlObservable
    {
        /// <summary>
        /// Wraps the source sequence in order to run its subscription and unsubscription logic on the Windows Forms message loop associated with the specified control.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="control">Windows Forms control 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 Windows Forms message loop associated with the specified control.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>
        /// <remarks>
        /// Only the side-effects of subscribing to the source sequence and disposing subscriptions to the source sequence are run on the specified control.
        /// In order to invoke observer callbacks on the specified control, e.g. to render results in a control, use <see cref="ObserveOn"/>.
        /// </remarks>
        public static IObservable<TSource> SubscribeOn<TSource>(this IObservable<TSource> source, Control control)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (control == null)
            {
                throw new ArgumentNullException(nameof(control));
            }

            return Synchronization.SubscribeOn(source, new ControlScheduler(control));
        }

        /// <summary>
        /// Wraps the source sequence in order to run its observer callbacks on the Windows Forms message loop associated with the specified control.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="control">Windows Forms control whose associated message loop is used to notify observers on.</param>
        /// <returns>The source sequence whose observations happen on the Windows Forms message loop associated with the specified control.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="control"/> is null.</exception>

View on GitHub (pinned to 94b5d5ab91)