dotnet/reactive · error · ArgumentNullException
source
Error message
source
What it means
This SelectMany overload projects each element into a WinRT IAsyncOperation and throws ArgumentNullException when the source observable is null (the selector null check follows). Rx validates arguments eagerly before composing the async-operation sequence.
Solutions
- Ensure the source observable is non-null before calling SelectMany
- Also verify the selector itself is non-null (next guard)
- Wrap optional sources: source ?? Observable.Empty<TSource>()
- Ensure async factories throw on failure rather than returning null observables
Example fix
// before IObservable<StorageFile> files = null; files.SelectMany(f => f.OpenAsync()).Subscribe(...); // after IObservable<StorageFile> files = GetFiles() ?? Observable.Empty<StorageFile>(); files.SelectMany(f => f.OpenAsync()).Subscribe(...);
Defensive patterns
Strategy: validation
Validate before calling
if (source == null) throw new ArgumentNullException(nameof(source)); if (selector == null) throw new ArgumentNullException(nameof(selector));
Type guard
static IObservable<TResult> SafeSelectMany<T, TResult>(IObservable<T> source, Func<T, Windows.Foundation.IAsyncOperation<TResult>> selector) => source?.SelectMany(selector) ?? Observable.Empty<TResult>();
Try / catch
try { obs.SelectMany(x => x.DoAsync()).Subscribe(...); }
catch (ArgumentNullException ex) { Log($"{ex.ParamName} null in SelectMany"); } Prevention
- Ensure async factories return empty observables instead of null on failure
- Guard null-conditional chains feeding Rx operators
- Default observable fields to Observable.Never or Observable.Empty
- Enable nullable reference types so null sources surface at compile time
When it happens
Trigger: Calling source.SelectMany(x => x.DoAsync()) where source is a null IObservable<TSource>, or where an upstream factory returned null; the selector returning null is a separate failure at runtime.
Common situations: Chaining SelectMany after a null-conditional expression on an optional service; passing the result of an async factory that returned null instead of throwing; WinRT async interop where the source was conditionally created.
Related errors
- Value cannot be null. (Parameter 'progress')
- Value cannot be null. (Parameter 'observer')
- observableFactory
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'scheduler')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/11dca0a7b884a61a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Platforms/WinRT/Linq/WindowsObservable.StandardSequenceOperators.cs:27
namespace System.Reactive.Linq
{
public static partial class WindowsObservable
{
/// <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>
/// <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>View on GitHub (pinned to 94b5d5ab91)