dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'newCollector')

Error message

Value cannot be null. (Parameter 'newCollector')

What it means

System.ArgumentNullException thrown by Observable.Collect(source, newCollector, merge) when the newCollector factory delegate is null. Rx validates each argument in order (source, newCollector, merge) so this fires only when source is non-null but the collector factory is not supplied.

Solutions

  1. Supply a valid Func<TResult> factory, e.g. () => default or () => new Accumulator().
  2. If the seed may be absent, guard with a null-coalescing default delegate before calling.
  3. Check that any delegate variable/field is initialized before being passed in.

Example fix

// before
var result = source.Collect(collectorFactory, (acc, x) => acc + x); // collectorFactory == null
// after
var result = source.Collect(() => 0, (acc, x) => acc + x);
Defensive patterns

Strategy: validation

Validate before calling

if (newCollector is null) throw new InvalidOperationException("Collect requires a non-null collector factory");
var safeFactory = newCollector ?? (() => default(TResult));

Type guard

bool HasFactory<TResult>(Func<TResult>? f) => f is not null;

Try / catch

try
{
    var result = source.Collect(newCollector, merge);
}
catch (ArgumentNullException ex) when (ex.ParamName == "newCollector")
{
    // fall back to a default seed factory
}

Prevention

When it happens

Trigger: Calling Collect with a null second argument, e.g. Collect(source, null, (acc, x) => ...) — typically when the delegate is built dynamically, retrieved from config/reflection, or a lambda was accidentally omitted.

Common situations: Passing a method group that resolves to null (e.g. a nullable Func field), constructing the call generically where the collector seed is optional, refactoring that renamed/removed the seed factory.

Related errors


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

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Blocking.cs:54

        /// Produces an enumerable sequence that returns elements collected/aggregated from the source sequence between consecutive iterations.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TResult">The type of the elements produced by the merge operation during collection.</typeparam>
        /// <param name="source">Source observable sequence.</param>
        /// <param name="newCollector">Factory to create a new collector object.</param>
        /// <param name="merge">Merges a sequence element with the current collector.</param>
        /// <returns>The enumerable sequence that returns collected/aggregated elements from the source sequence upon each iteration.</returns>
        /// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="newCollector"/> or <paramref name="merge"/> is null.</exception>
        public static IEnumerable<TResult> Collect<TSource, TResult>(this IObservable<TSource> source, Func<TResult> newCollector, Func<TResult, TSource, TResult> merge)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

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

            return s_impl.Collect(source, newCollector, merge);
        }

        /// <summary>
        /// Produces an enumerable sequence that returns elements collected/aggregated from the source sequence between consecutive iterations.
        /// </summary>
        /// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
        /// <typeparam name="TResult">The type of the elements produced by the merge operation during collection.</typeparam>
        /// <param name="source">Source observable sequence.</param>
        /// <param name="getInitialCollector">Factory to create the initial collector object.</param>
        /// <param name="merge">Merges a sequence element with the current collector.</param>

View on GitHub (pinned to 94b5d5ab91)