dotnet/reactive · error · ArgumentNullException
resultSelector
Error message
resultSelector
What it means
System.Reactive's 14-source Zip overload throws ArgumentNullException when the resultSelector delegate is null. The Zip operator eagerly validates all arguments before subscribing so failures surface synchronously at the call site rather than inside the observable pipeline. A null selector would make it impossible to combine the zipped elements.
Solutions
- Pass a non-null result selector lambda or method group as the 15th argument
- If the selector may be absent, guard with a default selector (e.g. (a1,...,a14) => default(TResult)) or use Tuple/ValueTuple creation instead
- Trace the variable holding the selector upstream to find where it became null
Example fix
// before Observable.Zip(s1, s2, /* ... */ s14, null); // after Observable.Zip(s1, s2, /* ... */ s14, (v1, v2, /* ... */ v14) => Combine(v1, v2 /* ... */));
Defensive patterns
Strategy: validation
Validate before calling
if (resultSelector is null) throw new ArgumentNullException(nameof(resultSelector));
Type guard
bool IsValidSelector<T1,...,T14,TResult>(Func<T1,...,T14,TResult>? f) => f is not null;
Try / catch
try
{
var zipped = Observable.Zip(s1, ..., s14, resultSelector);
}
catch (ArgumentNullException ex) when (ex.ParamName == nameof(resultSelector))
{
// supply a fallback selector or log and abort composition
} Prevention
- Never pass nullable Func variables directly to Zip; ensure assignment before composition
- Prefer method groups or named lambdas over computed delegates that can be null
- Enable nullable reference types so null delegate flow is caught at compile time
When it happens
Trigger: Calling Observable.Zip(source1..source14, resultSelector) where the 15th argument (Func<...,-,TResult>) is null, e.g. passing a variable that was never assigned or a method group that resolved to null.
Common situations: Storing the selector in a field/variable initialized later or conditionally; refactoring that removed a lambda but left the argument; reflection- or DI-composed pipelines supplying a null delegate.
Related errors
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/c79036b337b14c5a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.Zip.cs:923
if (source12 == null)
{
throw new ArgumentNullException(nameof(source12));
}
if (source13 == null)
{
throw new ArgumentNullException(nameof(source13));
}
if (source14 == null)
{
throw new ArgumentNullException(nameof(source14));
}
if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.Zip(source1, source2, source3, source4, source5, source6, source7, source8, source9, source10, source11, source12, source13, source14, resultSelector);
}
/// <summary>
/// Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index.
/// </summary>
/// <typeparam name="TSource1">The type of the elements in the first source sequence.</typeparam>
/// <typeparam name="TSource2">The type of the elements in the second source sequence.</typeparam>
/// <typeparam name="TSource3">The type of the elements in the third source sequence.</typeparam>
/// <typeparam name="TSource4">The type of the elements in the fourth source sequence.</typeparam>
/// <typeparam name="TSource5">The type of the elements in the fifth source sequence.</typeparam>
/// <typeparam name="TSource6">The type of the elements in the sixth source sequence.</typeparam>
/// <typeparam name="TSource7">The type of the elements in the seventh source sequence.</typeparam>
/// <typeparam name="TSource8">The type of the elements in the eighth source sequence.</typeparam>
/// <typeparam name="TSource9">The type of the elements in the ninth source sequence.</typeparam>
/// <typeparam name="TSource10">The type of the elements in the tenth source sequence.</typeparam>View on GitHub (pinned to 94b5d5ab91)