dotnet/reactive · error · ArgumentNullException
new ArgumentNullException(nameof(resultSelector))
Error message
new ArgumentNullException(nameof(resultSelector))
What it means
The fully-async Generate overload throws ArgumentNullException when the resultSelector delegate is null. resultSelector maps each state to the emitted TResult; without it the operator cannot produce output, so the null check runs before the work is scheduled on the IAsyncScheduler.
Solutions
- Provide a real resultSelector, e.g. s => new ValueTask<TResult>(Project(s)).
- If projection is trivial, pass an identity-style lambda such as s => new ValueTask<TState>(s) when TState == TResult.
- Assert/validate the delegate at composition time with ArgumentNullException.ThrowIfNull(resultSelector) in your own factory before delegating to Generate.
Example fix
// before
Generate(observer, 0, cond, iter, null, timeSel, sched); // throws
// after
Generate(observer, 0, cond, iter, s => new ValueTask<string>("v" + s), timeSel, sched); Defensive patterns
Strategy: validation
Validate before calling
if (resultSelector == null) throw new ArgumentNullException(nameof(resultSelector));
Type guard
static bool HasSelector<TState, TResult>(Func<TState, ValueTask<TResult>> sel) => sel is not null;
Try / catch
try { await Generate(observer, state, cond, iter, sel, timeSel, sched); } catch (ArgumentNullException ex) when (ex.ParamName == "resultSelector") { /* supply fallback selector */ } Prevention
- Check DI/config maps for every delegate argument before composing the query.
- Prefer method groups over nullable lambda variables.
- Add unit tests that exercise each Generate overload with real delegates.
When it happens
Trigger: Calling Generate(observer, initialState, condition, iterate, resultSelector, timeSelector, scheduler) with ValueTask delegates (Generate.cs:345) and passing null for Func<TState, ValueTask<TResult>> resultSelector.
Common situations: Wiring selectors from a mapping table or DI container where the entry for resultSelector is missing; copy-pasting an overload call and forgetting to supply the result selector; conditional delegate assignment that evaluates to null.
Related errors
- new ArgumentNullException(nameof(iterate))
- new ArgumentNullException(nameof(timeSelector))
- new ArgumentNullException(nameof(scheduler))
- Value cannot be null. (Parameter 'disposable1')
- Value cannot be null. (Parameter 'disposable2')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2d5c413de1a3e13b.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Generate.cs:354
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)
{
var hasResult = false;
var result = default(TResult);
var nextDue = default(TimeSpan);
try
{View on GitHub (pinned to 94b5d5ab91)