dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'getInitialCollector')

Error message

Value cannot be null. (Parameter 'getInitialCollector')

What it means

System.ArgumentNullException thrown by the 4-argument Observable.Collect overload when getInitialCollector is null. This is the seed-factory delegate producing the initial accumulator; Rx rejects it before the enumerable is returned.

Solutions

  1. Supply a valid Func<TResult> seed factory, e.g. () => 0.
  2. Check argument order — the overload overloads look similar; ensure the seed lambda is the 2nd argument.
  3. Initialize delegate fields/properties before use.

Example fix

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

Strategy: validation

Validate before calling

if (getInitialCollector is null) throw new InvalidOperationException("Collect requires a non-null initial collector factory");

Try / catch

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

Prevention

When it happens

Trigger: Calling Collect(source, null, merge, getNewCollector) — commonly a misordered call, an uninitialized Func field, or a factory method returning null.

Common situations: Constructing aggregation pipelines from configuration where the seed expression failed to bind; refactoring that swapped argument positions between the 3-arg and 4-arg overloads.

Related errors


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

Appendix: source

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

        /// </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>
        /// <param name="getNewCollector">Factory to replace the current collector by a new 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="getInitialCollector"/> or <paramref name="merge"/> or <paramref name="getNewCollector"/> is null.</exception>
        public static IEnumerable<TResult> Collect<TSource, TResult>(this IObservable<TSource> source, Func<TResult> getInitialCollector, Func<TResult, TSource, TResult> merge, Func<TResult, TResult> getNewCollector)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

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

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

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

            return s_impl.Collect(source, getInitialCollector, merge, getNewCollector);
        }

        #endregion

        #region + First +

View on GitHub (pinned to 94b5d5ab91)