dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'collectionSelector')
Error message
Value cannot be null. (Parameter 'collectionSelector')
What it means
In this SelectMany overload the collectionSelector (Func<TSource, IObservable<TCollection>>) determines the inner sequence for each element; it must not be null. The method validates all three arguments eagerly and throws ArgumentNullException naming 'collectionSelector' when it is null.
Solutions
- Provide a real collection selector: source.SelectMany(x => x.Children.ToObservable(), (x, c) => ...).
- Guard dynamic delegates: if (collectionSelector == null) collectionSelector = x => Observable.Empty<TCollection>();
- Confirm the argument order — collectionSelector comes before resultSelector; a swapped/null argument can trigger this.
Example fix
// before Func<Order, IObservable<Item>> items = null; var q = orders.SelectMany(items, (o, i) => i.Price); // after var q = orders.SelectMany(o => o.Items.ToObservable(), (o, i) => i.Price);
Defensive patterns
Strategy: validation
Validate before calling
if (collectionSelector is null)
collectionSelector = static _ => Observable.Empty<TCollection>(); Type guard
static bool HasCollSelector<TSrc, TColl>(Func<TSrc, IObservable<TColl>> sel) => sel is not null;
Try / catch
try
{
var q = source.SelectMany(collectionSelector, resultSelector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "collectionSelector")
{
throw new InvalidOperationException("Collection selector missing in SelectMany composition", ex);
} Prevention
- Inline the collection selector lambda at the call site whenever possible
- For dynamic query builders, require non-null delegates in the builder's Build() step
- Watch argument order: collectionSelector before resultSelector
When it happens
Trigger: source.SelectMany(null, (x, c) => result) or passing a null delegate variable into the collectionSelector slot while resultSelector is valid. Thrown at Observable.StandardSequenceOperators.cs:1190.
Common situations: Query-builder patterns where the collection selector is composed conditionally and ends up null; DI/config-injected projection functions that failed to resolve; refactors renaming a method but leaving a null delegate reference.
Related errors
- ArgumentNullException(nameof(resultSelector))
- throw new…
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2ed70dbfa24249d8.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.StandardSequenceOperators.cs:1190
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TCollection">The type of the elements in the projected intermediate sequences.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate sequence elements.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="collectionSelector">A transform function to apply to each element.</param>
/// <param name="resultSelector">A transform function to apply to each element of the intermediate sequence.</param>
/// <returns>An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="collectionSelector"/> or <paramref name="resultSelector"/> is null.</exception>
public static IObservable<TResult> SelectMany<TSource, TCollection, TResult>(this IObservable<TSource> source, Func<TSource, IObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (collectionSelector == null)
{
throw new ArgumentNullException(nameof(collectionSelector));
}
if (resultSelector == null)
{
throw new ArgumentNullException(nameof(resultSelector));
}
return s_impl.SelectMany(source, collectionSelector, resultSelector);
}
/// <summary>
/// Projects each element of an observable sequence to an observable sequence by incorporating the element's index, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TCollection">The type of the elements in the projected intermediate sequences.</typeparam>
/// <typeparam name="TResult">The type of the elements in the result sequence, obtained by using the selector to combine source sequence elements with their corresponding intermediate sequence elements.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="collectionSelector">A transform function to apply to each element; the second parameter of the function represents the index of the source element.</param>View on GitHub (pinned to 94b5d5ab91)