dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'handlers')
Error message
Value cannot be null. (Parameter 'handlers')
What it means
AsyncObserver.Concat<TSource>(observer, handlers) throws ArgumentNullException naming 'handlers' when the IEnumerator<IAsyncObservable<TSource>> is null. The enumerator supplies the sequences to be concatenated, so it cannot be null (an empty enumerator is fine).
Solutions
- Pass a non-null IEnumerator<IAsyncObservable<TSource>>
- Guard the source collection first: if (list == null) use an empty list's enumerator
- Default to an empty enumerator to mean 'concatenate nothing' rather than null
Example fix
// before var (sink, disp) = AsyncObserver.Concat(observer, sources.GetEnumerator()); // sources is null // after var enumerator = (sources ?? new List<IAsyncObservable<int>>()).GetEnumerator(); var (sink, disp) = AsyncObserver.Concat(observer, enumerator);
Defensive patterns
Strategy: validation
Validate before calling
if (handlers is null) handlers = (Enumerable.Empty<IAsyncObservable<TSource>>()).GetEnumerator();
Type guard
public static bool HasHandlers<T>(IEnumerator<IAsyncObservable<T>>? e) => e is not null;
Try / catch
try { var (sink, disp) = AsyncObserver.Concat(observer, handlers); }
catch (ArgumentNullException ex) when (ex.ParamName == "handlers") { /* use an empty enumerator */ } Prevention
- Null-check the source collection before calling GetEnumerator()
- Represent 'no sequences' with an empty enumerator, never null
- Null-coalesce collections from config/DI before enumerating
When it happens
Trigger: Calling AsyncObserver.Concat(observer, null), e.g. passing result of a method that returned null instead of an enumerator, or passing the enumerator of a null collection.
Common situations: Dynamic source lists from config/DI where obtaining the enumerator happened on a null collection; mapping null lists to enumerators without a null check.
Related errors
- Value cannot be null. (Parameter 'first')
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'sources')
- 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/0329d7e95e35973f.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Concat.cs:92
observer.OnNextAsync,
observer.OnErrorAsync,
async () =>
{
var secondSubscription = await second.SubscribeSafeAsync(observer).ConfigureAwait(false);
await subscription.AssignAsync(secondSubscription).ConfigureAwait(false);
}
);
return (sink, subscription);
}
public static (IAsyncObserver<TSource>, IAsyncDisposable) Concat<TSource>(IAsyncObserver<TSource> observer, IEnumerator<IAsyncObservable<TSource>> handlers)
{
if (observer == null)
throw new ArgumentNullException(nameof(observer));
if (handlers == null)
throw new ArgumentNullException(nameof(handlers));
var innerSubscription = new SerialAsyncDisposable();
IAsyncObserver<TSource> GetSink() =>
Create<TSource>(
observer.OnNextAsync,
observer.OnErrorAsync,
async () =>
{
var next = default(IAsyncObservable<TSource>);
try
{
if (handlers.MoveNext())
{
next = handlers.Current;
}
}View on GitHub (pinned to 94b5d5ab91)