dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

The scheduler-overload of Observable.Generate throws ArgumentNullException when the 'scheduler' argument is null. The overload needs an IScheduler to schedule each generation step; Rx checks it explicitly so the caller gets a precise error instead of an internal failure.

Solutions

  1. Pass a real scheduler such as Scheduler.Default, TaskPoolScheduler.Default, or NewThreadScheduler.Default
  2. Ensure the injected IScheduler is registered/resolved before use
  3. Null-check the scheduler before calling

Example fix

// before
Observable.Generate(0, c, i => i + 1, i => i, injectedScheduler) // injectedScheduler == null
// after
var sched = injectedScheduler ?? Scheduler.Default;
Observable.Generate(0, c, i => i + 1, i => i, sched)
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler == null) throw new ArgumentNullException(nameof(scheduler));
var sched = scheduler ?? Scheduler.Default;

Type guard

bool HasScheduler(IScheduler s) => s is not null;

Try / catch

try { Observable.Generate(state, cond, it, sel, sched); } catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* fall back to Scheduler.Default */ }

Prevention

When it happens

Trigger: Calling Observable.Generate<TState, TResult>(initialState, condition, iterate, resultSelector, null), e.g. a scheduler resolved from DI or a static field that is still null.

Common situations: Testing code where a scheduler mock was not registered; swapping Scheduler.Default for an injected scheduler that failed to resolve; initializing schedulers in a static ctor that ran out of order.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Creation.cs:408

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

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

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

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

            return s_impl.Generate(initialState, condition, iterate, resultSelector, scheduler);
        }

        #endregion

        #region + Never +

        /// <summary>
        /// Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins).
        /// </summary>
        /// <typeparam name="TResult">The type used for the <see cref="IObservable{T}"/> type parameter of the resulting sequence.</typeparam>
        /// <returns>An observable sequence whose observers will never get called.</returns>
        public static IObservable<TResult> Never<TResult>()
        {
            return s_impl.Never<TResult>();
        }

View on GitHub (pinned to 94b5d5ab91)