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
- Supply a valid Func<TResult> factory, e.g. () => default or () => new Accumulator().
- If the seed may be absent, guard with a null-coalescing default delegate before calling.
- 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
- Always pass an explicit lambda for the seed factory rather than a nullable delegate variable.
- Keep delegate arguments inline where possible to avoid null indirection.
- Use nullable reference type annotations on Func fields to surface uninitialized delegates.
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
- action (Parameter 'action')
- action
- Value cannot be null. (Parameter 'selector')
- Value cannot be null. (Parameter 'merge')
- Value cannot be null. (Parameter 'getInitialCollector')
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)