dotnet/reactive · error · ArgumentNullException

new ArgumentNullException(nameof(observer))

Error message

new ArgumentNullException(nameof(observer))

What it means

The explicit-scheduler Generate overload's first validation throws ArgumentNullException(nameof(observer)) when the IAsyncObserver<TResult> argument is null. This overload performs all delegate and scheduler checks itself (no shorter overload delegates to it with defaults for observer).

Solutions

  1. Pass a concrete IAsyncObserver<TResult> instance to Generate.
  2. Assert/require the observer in your composition code before building the operator pipeline.
  3. Fix the upstream factory/DI registration that produces a null observer.

Example fix

// before
await Generate(observerOrNull, 0, cond, iterate, select, timing, scheduler);
// after
if (observer == null) throw new InvalidOperationException("Observer not initialized");
await Generate(observer, 0, cond, iterate, select, timing, scheduler);
Defensive patterns

Strategy: validation

Validate before calling

if (observer == null) throw new InvalidOperationException("Observer not initialized");

Type guard

bool HasObserver<TResult>(IAsyncObserver<TResult> o) => o != null;

Try / catch

try { await Generate(observer, state, cond, iterate, select, timing, scheduler); }
catch (ArgumentNullException ex) when (ex.ParamName == "observer") { /* rebuild observer and retry once */ }

Prevention

When it happens

Trigger: Generate(null, initialState, condition, iterate, resultSelector, timeSelector, scheduler).

Common situations: Observer supplied by a factory or DI container that returned null; tests constructing the pipeline before creating the observer.

Related errors


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

Appendix: source

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

        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));
            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 (timeSelector == null)
                throw new ArgumentNullException(nameof(timeSelector));

            return Generate(observer, initialState, condition, iterate, resultSelector, timeSelector, TaskPoolAsyncScheduler.Default);
        }

        public static ValueTask<IAsyncDisposable> Generate<TState, TResult>(IAsyncObserver<TResult> observer, TState initialState, Func<TState, ValueTask<bool>> condition, Func<TState, ValueTask<TState>> iterate, Func<TState, ValueTask<TResult>> resultSelector, Func<TState, ValueTask<TimeSpan>> timeSelector, IAsyncScheduler scheduler)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));
            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 (timeSelector == null)
                throw new ArgumentNullException(nameof(timeSelector));
            if (scheduler == null)
                throw new ArgumentNullException(nameof(scheduler));

            return scheduler.ScheduleAsync(async ct =>
            {
                var first = true;
                var state = initialState;

                while (!ct.IsCancellationRequested)
                {

View on GitHub (pinned to 94b5d5ab91)