dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'handlers')
Error message
Value cannot be null. (Parameter 'handlers')
What it means
AsyncObserver.Catch<TSource>(observer, IEnumerator<IAsyncObservable<TSource>> handlers) requires an enumerator of fallback observables to try in sequence when errors occur. A null enumerator leaves no fallback sequence, so ArgumentNullException('handlers') is thrown after the observer check.
Solutions
- Ensure the source collection is non-null before calling GetEnumerator()
- Coalesce: (handlers ?? Enumerable.Empty<IAsyncObservable<int>>()).GetEnumerator()
- Fix the config/loader that produced the null handler list
Example fix
// before var (sink, disp) = AsyncObserver.Catch<int>(observer, configuredHandlers.GetEnumerator()); // configuredHandlers null // after var handlers = configuredHandlers ?? Enumerable.Empty<IAsyncObservable<int>>(); var (sink, disp) = AsyncObserver.Catch<int>(observer, handlers.GetEnumerator());
Defensive patterns
Strategy: validation
Validate before calling
if (observer is null) throw new ArgumentNullException(nameof(observer)); if (handlers is null) throw new ArgumentNullException(nameof(handlers));
Type guard
bool HasHandlerList<T>(IEnumerator<IAsyncObservable<T>> handlers) => handlers != null;
Try / catch
try { var (sink, d) = AsyncObserver.Catch<T>(observer, handlers); } catch (ArgumentNullException ex) when (ex.ParamName == "handlers") { /* enumerate a non-null collection */ } Prevention
- Never call GetEnumerator() on a possibly-null collection; coalesce first
- Treat empty handler lists as valid (observer completes on error)
- Load fallback lists with non-null defaults
When it happens
Trigger: Passing null instead of an IEnumerator — e.g. calling handlers.GetEnumerator() on a null collection, or forwarding a nullable enumerator parameter from a caller.
Common situations: Retry lists read from configuration that can be empty/null, so GetEnumerator() is invoked on a null sequence.
Related errors
- Value cannot be null. (Parameter 'onNextAsync')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'second')
- Value cannot be null. (Parameter 'sources')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/79bc07ce9c132aca.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Catch.cs:188
observer.OnNextAsync,
async ex =>
{
var secondSubscription = await second.SubscribeSafeAsync(observer).ConfigureAwait(false);
await subscription.AssignAsync(secondSubscription).ConfigureAwait(false);
},
observer.OnCompletedAsync
);
return (sink, subscription);
}
public static (IAsyncObserver<TSource>, IAsyncDisposable) Catch<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,
async ex =>
{
var handler = default(IAsyncObservable<TSource>);
try
{
if (handlers.MoveNext())
{
handler = handlers.Current;
}
}
catch (Exception err)View on GitHub (pinned to 94b5d5ab91)