dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'condition')

Error message

Value cannot be null. (Parameter 'condition')

What it means

The scheduler-less overload Generate<TState,TResult>(initialState, condition, iterate, resultSelector) throws ArgumentNullException when the condition delegate is null. Generate evaluates condition before every iteration, so a null predicate would be unobservable until runtime; the library validates eagerly. This is fail-fast argument validation of the caller's delegates.

Solutions

  1. Supply a valid Func<TState, ValueTask<bool>> condition delegate, e.g. state => new ValueTask<bool>(state < limit).
  2. If the condition comes from a variable/expression, assert it is non-null before calling Generate and fix the producer.
  3. Use a helper to wrap a sync predicate when only Func<TState,bool> is available: s => new ValueTask<bool>(syncPred(s)).

Example fix

// before
var xs = AsyncObservable.Generate(0, (Func<int, ValueTask<bool>>)null, i => new ValueTask<int>(i + 1), i => new ValueTask<int>(i));
// after
var xs = AsyncObservable.Generate(0, i => new ValueTask<bool>(i < 10), i => new ValueTask<int>(i + 1), i => new ValueTask<int>(i));
Defensive patterns

Strategy: validation

Validate before calling

if (condition is null) condition = s => new ValueTask<bool>(true); // or throw early
var xs = AsyncObservable.Generate(initialState, condition, iterate, resultSelector);

Type guard

static bool IsValidCondition<TState>(Func<TState, ValueTask<bool>> c) => c is not null;

Try / catch

try { var xs = AsyncObservable.Generate(state, cond, iter, sel); }
catch (ArgumentNullException ex) when (ex.ParamName == "condition") { /* supply a default predicate and retry */ }

Prevention

When it happens

Trigger: Calling Generate(initialState, null, iterate, resultSelector) — the 4-argument ValueTask-based overload at Generate.cs:41 ('if (condition == null) throw new ArgumentNullException(nameof(condition))').

Common situations: Building the predicate dynamically (e.g. from a filter expression) and the expression compiler returning null; copying a call from another overload and forgetting the condition argument; DI-injected predicate delegate not registered.

Related errors


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

Appendix: source

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

        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)
        {
            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));

View on GitHub (pinned to 94b5d5ab91)