dotnet/reactive · error · ArgumentNullException

ArgumentNullException (default message: Value cannot be…

Error message

ArgumentNullException (default message: Value cannot be null. (Parameter 'accumulator'))

What it means

Scan throws ArgumentNullException when the `accumulator` function is null. The accumulator is required to fold each element into the running value; without it the operator cannot be constructed, so Rx throws immediately.

Solutions

  1. Pass a valid Func<TAccumulate, TSource, TAccumulate>.
  2. Fix the reducer lookup/factory returning null.
  3. Provide a default accumulator for the configured aggregation mode.

Example fix

// before
var reducer = _reducers.TryGetValue(kind, out var r) ? r : null;
var sum = source.Scan(0, reducer);
// after
var reducer = _reducers.TryGetValue(kind, out var r) ? r : (acc, x) => acc + x;
var sum = source.Scan(0, reducer);
Defensive patterns

Strategy: validation

Validate before calling

if (accumulator is null) throw new ArgumentNullException(nameof(accumulator));
var sum = source.Scan(seed, accumulator);

Type guard

bool IsValidAccumulator<TAcc,TSource>(Func<TAcc,TSource,TAcc>? f) => f is not null;

Try / catch

try { sum = source.Scan(seed, acc); }
catch (ArgumentNullException ex) when (ex.ParamName == "accumulator") { sum = source.Scan(seed, (a, _) => a); }

Prevention

When it happens

Trigger: Calling Scan(source, seed, accumulator) with a null accumulator delegate (line 714 check).

Common situations: Selecting an aggregation function from a dictionary/registry of reducers that lacks the requested key; passing a method group on a null object obtained via reflection.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Single.cs:714

        /// For aggregation behavior with no intermediate results, see <see cref="Observable.Aggregate{TSource, Accumulate}"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TAccumulate">The type of the result of the aggregation.</typeparam>
        /// <param name="source">An observable sequence to accumulate over.</param>
        /// <param name="seed">The initial accumulator value.</param>
        /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
        /// <returns>An observable sequence containing the accumulated values.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
        public static IObservable<TAccumulate> Scan<TSource, TAccumulate>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (accumulator == null)
            {
                throw new ArgumentNullException(nameof(accumulator));
            }

            return s_impl.Scan(source, seed, accumulator);
        }

        /// <summary>
        /// Applies an accumulator function over an observable sequence and returns each intermediate result.
        /// For aggregation behavior with no intermediate results, see <see cref="Observable.Aggregate{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 accumulate over.</param>
        /// <param name="accumulator">An accumulator function to be invoked on each element.</param>
        /// <returns>An observable sequence containing the accumulated values.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="accumulator"/> is null.</exception>
        public static IObservable<TSource> Scan<TSource>(this IObservable<TSource> source, Func<TSource, TSource, TSource> accumulator)
        {
            if (source == null)
            {

View on GitHub (pinned to 94b5d5ab91)