dotnet/reactive · error · ArgumentNullException

scheduler

Error message

scheduler

What it means

The Case(selector, sources, scheduler) overload throws ArgumentNullException when the IScheduler is null. The scheduler controls which context the default branch (Observable.Empty) is subscribed on, and this overload requires an explicit one, rejected at Observable.Imperative.cs:176.

Solutions

  1. Pass a concrete scheduler such as Scheduler.Default, Scheduler.Immediate, or Scheduler.CurrentThread.
  2. Fix the DI/config resolution that was supposed to supply the IScheduler.
  3. Use Scheduler.Default as a fallback when a resolved scheduler is null.

Example fix

// before
var sched = _schedulers.GetValueOrDefault(name); // null if name unknown
Observable.Case(selector, sources, sched);
// after
var sched = _schedulers.GetValueOrDefault(name) ?? Scheduler.Default;
Observable.Case(selector, sources, sched);
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler is null) throw new ArgumentNullException(nameof(scheduler));
var result = Observable.Case(selector, sources, scheduler);

Try / catch

try { var q = Observable.Case(selector, sources, scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* fall back to Scheduler.Default */ }

Prevention

When it happens

Trigger: Calling Observable.Case(selector, sources, scheduler) with a null IScheduler, e.g. a scheduler resolved from config or DI that was not registered.

Common situations: Scheduler injected via constructor left uninitialized; passing a null scheduler in unit tests; a resolution helper returning null when the scheduler name is unknown.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Imperative.cs:176

        /// <param name="scheduler">Scheduler to generate an empty sequence on in case no matching source in <paramref name="sources"/> is found.</param>
        /// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> or <paramref name="scheduler"/> is null.</exception>
        public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources, IScheduler scheduler)
            where TValue : notnull
        {
            if (selector == null)
            {
                throw new ArgumentNullException(nameof(selector));
            }

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

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

            return s_impl.Case(selector, sources, scheduler);
        }

        /// <summary>
        /// Uses <paramref name="selector"/> to determine which source in <paramref name="sources"/> to return, choosing an empty sequence if no match is found.
        /// </summary>
        /// <typeparam name="TValue">The type of the value returned by the selector function, used to look up the resulting source.</typeparam>
        /// <typeparam name="TResult">The type of the elements in the result sequence.</typeparam>
        /// <param name="selector">Selector function invoked to determine the source to lookup in the <paramref name="sources"/> dictionary.</param>
        /// <param name="sources">Dictionary of sources to select from based on the <paramref name="selector"/> invocation result.</param>
        /// <returns>The observable sequence retrieved from the <paramref name="sources"/> dictionary based on the <paramref name="selector"/> invocation result, or an empty sequence if no match is found.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="selector"/> or <paramref name="sources"/> is null.</exception>
        public static IObservable<TResult> Case<TValue, TResult>(Func<TValue> selector, IDictionary<TValue, IObservable<TResult>> sources)
            where TValue : notnull
        {
            if (selector == null)

View on GitHub (pinned to 94b5d5ab91)