dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'selector')
Error message
Value cannot be null. (Parameter 'selector')
What it means
The AsyncObserver.SelectMany overload (observer, Func<TSource, IAsyncObservable<TResult>> selector) throws ArgumentNullException because the selector parameter was null. The selector maps each source element to an inner async observable; a null selector leaves the operator unable to project elements, so it is rejected at construction time.
Solutions
- Provide a real selector, e.g. x => AsyncObservable.Return(x * 2) or a method group like Project.
- If the selector may be absent, fall back to an identity-based projection such as x => AsyncObservable.Empty<TResult>() rather than null.
- Initialize delegate-typed members/fields with a default projection.
- Validate at the call site before constructing the operator.
Example fix
// before var (obs, disp) = AsyncObserver.SelectMany<TSource, TResult>(downstream, null); // after Func<TSource, IAsyncObservable<TResult>> selector = ProjectElement; var (obs, disp) = AsyncObserver.SelectMany(downstream, selector);
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer)); if (selector is null) throw new ArgumentNullException(nameof(selector));
Type guard
static bool IsValid<TSource, TResult>(
IAsyncObserver<TResult> observer,
Func<TSource, IAsyncObservable<TResult>> selector)
=> observer is not null && selector is not null; Try / catch
try
{
var (obs, disp) = AsyncObserver.SelectMany(observer, selector);
}
catch (ArgumentNullException ex) when (ex.ParamName == "selector")
{
selector = x => AsyncObservable.Empty<TResult>();
} Prevention
- Initialize delegate-typed members with a default projection instead of null.
- Resolve selectors from configuration with a fallback identity/default projection.
- Keep argument order matched to the overload signature when editing call sites.
When it happens
Trigger: Calling AsyncObserver.SelectMany(observer, null) with the sync-observable-selector overload, or passing a selector field/property that is still null (e.g. uninitialized delegate member).
Common situations: DI or configuration supplying the projection function lazily and failing, casting a method group from an object whose method is null, or refactoring where the selector argument was accidentally deleted.
Related errors
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'observer')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/2ff10f2f45ac91b9.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/SelectMany.cs:189
static async (source, state, observer) =>
{
var (sink, inner) = AsyncObserver.SelectMany(observer, state.collectionSelector, state.resultSelector);
var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, inner);
});
}
}
public partial class AsyncObserver
{
public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TResult>(IAsyncObserver<TResult> observer, Func<TSource, IAsyncObservable<TResult>> selector)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
return SelectMany<TSource, TResult, TResult>(observer, x => new ValueTask<IAsyncObservable<TResult>>(selector(x)), (x, y) => new ValueTask<TResult>(y));
}
public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TResult>(IAsyncObserver<TResult> observer, Func<TSource, ValueTask<IAsyncObservable<TResult>>> selector)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (selector == null)
throw new ArgumentNullException(nameof(selector));
return SelectMany<TSource, TResult, TResult>(observer, selector, (x, y) => new ValueTask<TResult>(y));
}
public static (IAsyncObserver<TSource>, IAsyncDisposable) SelectMany<TSource, TCollection, TResult>(IAsyncObserver<TResult> observer, Func<TSource, IAsyncObservable<TCollection>> collectionSelector, Func<TSource, TCollection, TResult> resultSelector)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));View on GitHub (pinned to 94b5d5ab91)