dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'handler')
Error message
Value cannot be null. (Parameter 'handler')
What it means
Catch<TSource,TException> requires a Func<TException, IAsyncObservable<TSource>> that produces the fallback stream; a null handler throws ArgumentNullException at operator construction. Without it the operator cannot react to the exception type.
Solutions
- Pass a real handler lambda, e.g. ex => AsyncObservable.Return<TValue>(fallbackValue)
- Default the handler to one that rethrows or returns Empty if no custom recovery is needed
- Null-check the configured handler before composing the operator
Example fix
// before var result = source.Catch<TimeoutException>(null); // after var result = source.Catch<TimeoutException>(ex => AsyncObservable.Empty<int>(Scheduler.Default));
Defensive patterns
Strategy: validation
Validate before calling
if (handler == null) throw new InvalidOperationException("Catch requires a non-null fallback handler"); Type guard
bool HasHandler<TException, TSource>(Func<TException, IAsyncObservable<TSource>> h) => h is not null;
Try / catch
try { var result = source.Catch<TimeoutException>(handler); }
catch (ArgumentNullException ex) when (ex.ParamName == "handler") { /* supply a default recovery handler */ } Prevention
- Default handlers to ex => Empty(scheduler) when no custom recovery exists
- Initialize handler fields at construction
- Keep sync and async overload usage consistent
When it happens
Trigger: Calling source.Catch<TException>(null) or Catch(source, (Func<TException, IAsyncObservable<TSource>>)null).
Common situations: Handler stored in a nullable field/config that was never set; conditional logic that skips assigning the fallback factory; refactoring swapped the ValueTask overload but cast the lambda to the wrong delegate type resulting in null.
Related errors
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'first')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'source')
- removeHandler
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/25b6690a04de9ef5.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Catch.cs:21
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
// TODO: Implement tail call behavior to flatten Catch chains.
public partial class AsyncObservable
{
public static IAsyncObservable<TSource> Catch<TSource, TException>(this IAsyncObservable<TSource> source, Func<TException, IAsyncObservable<TSource>> handler)
where TException : Exception
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (handler == null)
throw new ArgumentNullException(nameof(handler));
return Create(
source,
handler,
static async (source, handler, observer) =>
{
var (sink, inner) = AsyncObserver.Catch(observer, handler);
var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);
return StableCompositeAsyncDisposable.Create(subscription, inner);
});
}
public static IAsyncObservable<TSource> Catch<TSource, TException>(this IAsyncObservable<TSource> source, Func<TException, ValueTask<IAsyncObservable<TSource>>> handler)
where TException : Exception
{
if (source == null)View on GitHub (pinned to 94b5d5ab91)