dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'resultSelector')
Error message
Value cannot be null. (Parameter 'resultSelector')
What it means
The full Aggregate overload throws ArgumentNullException when resultSelector is null. The resultSelector converts the final accumulated value into the output type; without it the operator cannot produce a result, so validation fails synchronously before any subscription occurs.
Solutions
- Pass an identity selector, x => x, when no projection is needed.
- Switch to the 3-parameter overload (source, seed, accumulator) if no result projection is required.
- Default the selector to Func<TAccumulate, TResult> identity when resolved dynamically.
- Enable nullable reference types to catch the null selector at compile time.
Example fix
// before await src.Aggregate(0, (a, x) => a + x, null); // ArgumentNullException // after await src.Aggregate(0, (a, x) => a + x, x => x); // or use the 3-arg overload
Defensive patterns
Strategy: type-guard
Validate before calling
if (resultSelector is null) resultSelector = x => x; // identity fallback
Type guard
static Func<T, TResult> NotNull<T, TResult>(Func<T, TResult>? f) => f ?? (x => x!);
Try / catch
try { var result = source.Aggregate(seed, acc, selector); }
catch (ArgumentNullException ex) when (ex.ParamName == "resultSelector") { /* use identity selector or 3-arg overload */ } Prevention
- Use the 3-parameter Aggregate overload when no projection is needed.
- Pass x => x explicitly instead of null to signal identity projection.
- Default optional selectors to identity functions in wrapper APIs.
- Enable nullable reference types to catch null selectors statically.
When it happens
Trigger: Calling Observable.Aggregate(source, seed, accumulator, null) — e.g. omitting the projection because the accumulator already seemed sufficient, or passing a null conditional projection delegate.
Common situations: Refactors that replaced the selector with direct use of the accumulate type but left the 4-arg call; frameworks injecting an optional mapper that defaults to null; generic helpers where the selector parameter was never bound.
Related errors
- Value cannot be null. (Parameter 'accumulator')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/fbf800f9e0b8dbca.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs:69
/// <param name="resultSelector">A function to transform the final accumulator value into the result value.</param>
/// <returns>An observable sequence containing a single element with the final accumulator value.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> or <paramref name="resultSelector"/> is null.</exception>
/// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
public static IObservable<TResult> Aggregate<TSource, TAccumulate, TResult>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator, Func<TAccumulate, TResult> resultSelector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (accumulator == null)
{
throw new ArgumentNullException(nameof(accumulator));
}
if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Aggregate(source, seed, accumulator, resultSelector);
}
/// <summary>
/// Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence.
/// For aggregation behavior with incremental intermediate results, see <see cref="Observable.Scan{TSource}"/>.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence and the result of the aggregation.</typeparam>
/// <param name="source">An observable sequence to aggregate over.</param>
/// <param name="accumulator">An accumulator function to be invoked on each element.</param>
/// <returns>An observable sequence containing a single element with the final accumulator value.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
/// <exception cref="InvalidOperationException">(Asynchronous) The source sequence is empty.</exception>
/// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>
public static IObservable<TSource> Aggregate<TSource>(this IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
{View on GitHub (pinned to 94b5d5ab91)