dotnet/reactive · error · ArgumentNullException

provider

Error message

provider

What it means

When<TResult>(plans) is an extension on IQbservableProvider that matches a set of QueryablePlan objects; the provider itself must be non-null. The method throws ArgumentNullException("provider") when the receiver is null, since CreateQuery cannot be invoked on a null provider. The check precedes building the Expression.Call for the When operator.

Solutions

  1. Obtain a valid IQbservableProvider instance (e.g. from your Rx query service) before calling When.
  2. Verify the DI registration that supplies the provider.
  3. Guard with a null check and fail with a clearer application-level message if the provider is unavailable.

Example fix

// before
IQbservableProvider provider = ResolveProvider(); // null
var result = provider.When(plan1, plan2);
// after
IQbservableProvider provider = ResolveProvider() ?? throw new InvalidOperationException("No IQbservableProvider configured");
var result = provider.When(plan1, plan2);
Defensive patterns

Strategy: validation

Validate before calling

if (provider is null) throw new InvalidOperationException("No IQbservableProvider configured");
var result = provider.When(plans);

Type guard

bool HasProvider(IQbservableProvider? p) => p is not null;

Try / catch

try { var result = provider.When(plans); }
catch (ArgumentNullException ex) when (ex.ParamName == "provider") { throw new InvalidOperationException("Provider not initialized", ex); }

Prevention

When it happens

Trigger: Calling When(plans) through a null IQbservableProvider reference, or invoking the static method with provider: null explicitly.

Common situations: Using an IQbservableProvider obtained from a service locator or test harness that returned null instead of a real provider (e.g. TestScheduler-backed or remote provider).

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Qbservable.Joins.cs:90

                    source.Expression,
                    selector
                )
            );
        }

        /// <summary>
        /// Joins together the results from several patterns.
        /// </summary>
        /// <typeparam name="TResult">The type of the elements in the result sequence, obtained from the specified patterns.</typeparam>
        /// <param name="provider">Query provider used to construct the <see cref="IQbservable{T}"/> data source.</param>
        /// <param name="plans">A series of plans created by use of the Then operator on patterns.</param>
        /// <returns>An observable sequence with the results from matching several patterns.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="provider"/> or <paramref name="plans"/> is null.</exception>
        public static IQbservable<TResult> When<TResult>(this IQbservableProvider provider, params QueryablePlan<TResult>[] plans)
        {
            if (provider == null)
            {
                throw new ArgumentNullException(nameof(provider));
            }

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

            return provider.CreateQuery<TResult>(
                Expression.Call(
                    null,
                    new Func<IQbservableProvider, QueryablePlan<TResult>[], IQbservable<TResult>>(When).Method,
                    Expression.Constant(provider, typeof(IQbservableProvider)),
                    Expression.NewArrayInit(
                        typeof(QueryablePlan<TResult>),
                        plans.Select(p => p.Expression)
                    )
                )
            );

View on GitHub (pinned to 94b5d5ab91)