dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'sources')
Error message
Value cannot be null. (Parameter 'sources')
What it means
AsyncObservable.Concat<TSource>(params sources) and the IEnumerable overload throw ArgumentNullException naming 'sources' when the sequence of observables itself is null. Note: the params overload also throws if you pass a single null cast explicitly; the array itself must be non-null.
Solutions
- Pass a non-null collection of observables
- Default null collections to an empty array/list: sources ?? Array.Empty<IAsyncObservable<T>>()
- Fix the producer that returns null instead of an empty collection
Example fix
// before var merged = AsyncObservable.Concat(sources); // sources is null // after var merged = AsyncObservable.Concat(sources ?? Array.Empty<IAsyncObservable<int>>());
Defensive patterns
Strategy: validation
Validate before calling
var safeSources = sources ?? Array.Empty<IAsyncObservable<TSource>>();
Type guard
public static bool HasSources<T>(IEnumerable<IAsyncObservable<T>>? s) => s is not null;
Try / catch
try { var merged = AsyncObservable.Concat(sources); }
catch (ArgumentNullException ex) when (ex.ParamName == "sources") { /* use an empty collection */ } Prevention
- Never return null collections from producer methods; return empty ones
- Null-coalesce config/DI-provided collections before use
- Avoid casting null through the params overload with explicit casts
When it happens
Trigger: Calling Concat((IEnumerable<IAsyncObservable<TSource>>)null), or Concat(sources) where a method returning the collection returned null; also passing a null array through the params overload via an explicit cast.
Common situations: Dynamically built lists of sources from config or DI where the aggregation step returned null; serialization frameworks deserializing an absent collection to null.
Related errors
- Value cannot be null. (Parameter 'first')
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'handlers')
- Value cannot be null. (Parameter 'disposable1')
- Value cannot be null. (Parameter 'disposable2')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/12508eca6f07f290.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs:40
return Create(
first,
second,
static async (first, second, observer) =>
{
var (sink, inner) = AsyncObserver.Concat(observer, second);
var subscription = await first.SubscribeSafeAsync(sink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, inner);
});
}
public static IAsyncObservable<TSource> Concat<TSource>(params IAsyncObservable<TSource>[] sources) => Concat((IEnumerable<IAsyncObservable<TSource>>)sources);
public static IAsyncObservable<TSource> Concat<TSource>(this IEnumerable<IAsyncObservable<TSource>> sources)
{
if (sources == null)
throw new ArgumentNullException(nameof(sources));
return Create<TSource>(async observer =>
{
var enumerator = sources.GetEnumerator();
if (!enumerator.MoveNext())
{
return AsyncDisposable.Nop; // REVIEW: Is Never behavior right here?
}
var source = enumerator.Current;
var (sink, inner) = AsyncObserver.Concat(observer, enumerator);
var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, inner);
});View on GitHub (pinned to 94b5d5ab91)