dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'scheduler')

Error message

Value cannot be null. (Parameter 'scheduler')

What it means

System.Reactive.Async's Generate operator validates all delegate arguments up front and throws ArgumentNullException when the scheduler passed to the overload Generate<TState,TResult>(initialState, condition, iterate, resultSelector, IAsyncScheduler) is null. The library does this fail-fast at subscription-creation time so a null scheduler cannot surface later deep inside async scheduling machinery. It is a caller-contract violation, not an internal bug.

Solutions

  1. Pass a non-null IAsyncScheduler instance, e.g. AsyncScheduler.Default (or the appropriate immediate/new-thread scheduler) as the fifth argument.
  2. If no custom scheduling is needed, call the 4-argument overload Generate(initialState, condition, iterate, resultSelector) which omits the scheduler entirely.
  3. Null-check or require the scheduler at the call site (throw early with a clear message) before invoking Generate.

Example fix

// before
var xs = AsyncObservable.Generate(0, i => i < 10, i => i + 1, i => i, (IAsyncScheduler)null);
// after
var xs = AsyncObservable.Generate(0, i => i < 10, i => i + 1, i => i, AsyncScheduler.Default);
Defensive patterns

Strategy: validation

Validate before calling

if (scheduler is null) throw new InvalidOperationException("Generate requires a non-null IAsyncScheduler");
// then call Generate(initialState, condition, iterate, resultSelector, scheduler);

Type guard

static bool HasScheduler(IAsyncScheduler s) => s is not null;

Try / catch

try { var xs = AsyncObservable.Generate(0, c, i, r, sched); }
catch (ArgumentNullException ex) when (ex.ParamName == "scheduler") { /* fall back to scheduler-less overload or default scheduler */ }

Prevention

When it happens

Trigger: Calling System.Reactive.Async.Linq.Operators.Generate(initialState, condition, iterate, resultSelector, scheduler) with scheduler == null (line 33 of Generate.cs, the guard 'if (scheduler == null) throw new ArgumentNullException(nameof(scheduler))' in the IAsyncScheduler overload that delegates to AsyncObserver.Generate with 6 arguments).

Common situations: Passing a scheduler variable that was resolved from configuration/DI and came back null; refactoring code that previously called the parameterless-scheduler overload and leaving the last argument empty/nulled; a factory method returning null as the default scheduler.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Generate.cs:33

                throw new ArgumentNullException(nameof(condition));
            if (iterate == null)
                throw new ArgumentNullException(nameof(iterate));
            if (resultSelector == null)
                throw new ArgumentNullException(nameof(resultSelector));

            return Create<TResult>(observer => AsyncObserver.Generate(observer, initialState, condition, iterate, resultSelector));
        }

        public static IAsyncObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, bool> condition, Func<TState, TState> iterate, Func<TState, TResult> resultSelector, IAsyncScheduler scheduler)
        {
            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 Create<TResult>(observer => AsyncObserver.Generate(observer, initialState, condition, iterate, resultSelector, scheduler));
        }

        public static IAsyncObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, ValueTask<bool>> condition, Func<TState, ValueTask<TState>> iterate, Func<TState, ValueTask<TResult>> resultSelector)
        {
            if (condition == null)
                throw new ArgumentNullException(nameof(condition));
            if (iterate == null)
                throw new ArgumentNullException(nameof(iterate));
            if (resultSelector == null)
                throw new ArgumentNullException(nameof(resultSelector));

            return Create<TResult>(observer => AsyncObserver.Generate(observer, initialState, condition, iterate, resultSelector));
        }

        public static IAsyncObservable<TResult> Generate<TState, TResult>(TState initialState, Func<TState, ValueTask<bool>> condition, Func<TState, ValueTask<TState>> iterate, Func<TState, ValueTask<TResult>> resultSelector, IAsyncScheduler scheduler)
        {

View on GitHub (pinned to 94b5d5ab91)