dotnet/reactive · error · ArgumentNullException
ArgumentNullException: selector
Error message
ArgumentNullException: selector
What it means
This SelectMany overload (selector returning IAsyncOperation<TResult>) throws ArgumentNullException when the selector delegate is null. The selector is invoked per element to produce the WinRT async operation, so a null delegate makes the composition impossible. Validation is eager, before any subscription.
Solutions
- Supply a non-null selector lambda, e.g. x => x.CreateAsyncOperation().
- Null-check injected/configured selectors before building the query.
- Ensure DI registrations or factory methods actually provide the selector delegate.
Example fix
// before
Func<Item, IAsyncOperation<Result>> sel = _config.Selector; // may be null
var q = source.SelectMany(sel);
// after
var selector = _config.Selector ?? throw new InvalidOperationException("Selector not configured");
var q = source.SelectMany(x => selector(x)); Defensive patterns
Strategy: validation
Validate before calling
if (selector is null) throw new InvalidOperationException("selector delegate must be configured before SelectMany"); Type guard
static bool HasSelector<T, R>(Func<T, IAsyncOperation<R>>? f) => f is not null;
Try / catch
try { var q = source.SelectMany(selector); }
catch (ArgumentNullException ex) when (ex.ParamName == "selector") { /* fail with clear configuration error */ } Prevention
- Require selector delegates in constructors and validate with ArgumentNullException.ThrowIfNull at injection time.
- Avoid dictionary lookups for delegates without a TryGetValue + null check.
- Write selectors as inline lambdas when they are not genuinely dynamic.
When it happens
Trigger: Calling source.SelectMany<TSource, TResult>(selector) where the Func<TSource, IAsyncOperation<TResult>> argument is null.
Common situations: A selector stored in a field, injected dependency, or dictionary that was never initialized; passing a null method group from optional configuration; refactoring removed the lambda but left the call.
Related errors
- ArgumentNullException: source
- Value cannot be null. (Parameter 'asyncOperationSelector')
- Value cannot be null. (Parameter 'resultSelector')
- ArgumentNullException: elementSelector
- ArgumentNullException: source
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/b325a68e1425e476.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Linq/WindowsObservable.StandardSequenceOperators.cs:35
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <returns>An observable sequence whose elements are the result of the asynchronous operations executed for each element of the input sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
/// <remarks>This overload supports composition of observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable{TResult}(IAsyncOperation{TResult})"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TResult>(this IObservable<TSource> source, Func<TSource, IAsyncOperation<TResult>> selector)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (selector == null)
{
throw new ArgumentNullException(nameof(selector));
}
return source.SelectMany(x => selector(x).ToObservable());
}
/// <summary>
/// Projects each element of an observable sequence to a Windows Runtime asynchronous operation and merges all of the asynchronous operation results into one observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence.</typeparam>
/// <typeparam name="TResult">The type of the result produced by the projected asynchronous operations and the elements in the merged result sequence.</typeparam>
/// <typeparam name="TProgress">The type of the reported progress objects, which get ignored by this query operator.</typeparam>
/// <param name="source">An observable sequence of elements to project.</param>
/// <param name="selector">A transform function to apply to each element.</param>
/// <returns>An observable sequence whose elements are the result of the asynchronous operations executed for each element of the input sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="selector"/> is null.</exception>
/// <remarks>This overload supports composition of observable sequences and Windows Runtime asynchronous operations, without requiring manual conversion of the asynchronous operations to observable sequences using <see cref="AsyncInfoObservableExtensions.ToObservable{TResult}(IAsyncOperation{TResult})"/>.</remarks>
public static IObservable<TResult> SelectMany<TSource, TResult, TProgress>(this IObservable<TSource> source, Func<TSource, IAsyncOperationWithProgress<TResult, TProgress>> selector)
{View on GitHub (pinned to 94b5d5ab91)