dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'handler')
Error message
Value cannot be null. (Parameter 'handler')
What it means
The Catch<TSource, TException>(source, handler) overload throws ArgumentNullException when the handler Func<TException, IObservable<TSource>> is null. The handler supplies the fallback sequence for a matching exception, so it is required and validated synchronously at the call site.
Solutions
- Supply a concrete fallback handler, e.g. ex => Observable.Return(defaultValue).
- If no fallback exists, do not call Catch — or pass a handler that rethrows/returns Observable.Throw.
- Fix the config/dependency that was expected to provide the handler.
Example fix
// before Func<TimeoutException, IObservable<int>> fallback = maybeFallback; var resilient = source.Catch(fallback); // throws if maybeFallback is null // after var fallback = maybeFallback ?? (TimeoutException e) => Observable.Throw<int>(e); var resilient = source.Catch(fallback);
Defensive patterns
Strategy: validation
Validate before calling
ArgumentNullException.ThrowIfNull(handler); var handler = maybeHandler ?? ((TimeoutException e) => Observable.Throw<TSource>(e));
Type guard
bool HasHandler<TSource, TException>(Func<TException, IObservable<TSource>>? h) where TException : Exception => h is not null;
Try / catch
try { var q = source.Catch(handler); }
catch (ArgumentNullException ex) when (ex.ParamName == "handler") { /* supply a fallback handler or skip Catch */ } Prevention
- Only wrap with Catch when a fallback policy actually exists; otherwise omit the operator.
- Centralize fallback policies so handler delegates are always materialized (never null).
- Fail fast on missing policy configuration at application startup.
When it happens
Trigger: Calling source.Catch(handler) where handler is null — a fallback delegate field not yet assigned, a null strategy from config, or passing a variable holding a method group that was conditionally resolved to null.
Common situations: Policy/fallback configuration where no fallback was defined and null was passed instead of skipping Catch; dependency injection of a 'fallback provider' returning null; refactoring removed the lambda but the call remained.
Related errors
- Value cannot be null. (Parameter 'bufferOpenings')
- Value cannot be null. (Parameter 'bufferBoundaries')
- throw new ArgumentNullException(nameof(condition));
- source
- Value cannot be null. (Parameter 'onNextAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/b1b549d608b6d514.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs:181
/// <summary>
/// Continues an observable sequence that is terminated by an exception of the specified type with the observable sequence produced by the handler.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence and sequences returned by the exception handler function.</typeparam>
/// <typeparam name="TException">The type of the exception to catch and handle. Needs to derive from <see cref="Exception"/>.</typeparam>
/// <param name="source">Source sequence.</param>
/// <param name="handler">Exception handler function, producing another observable sequence.</param>
/// <returns>An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an exception occurred.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="handler"/> is null.</exception>
public static IObservable<TSource> Catch<TSource, TException>(this IObservable<TSource> source, Func<TException, IObservable<TSource>> handler) where TException : Exception
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (handler == null)
{
throw new ArgumentNullException(nameof(handler));
}
return s_impl.Catch(source, handler);
}
/// <summary>
/// Continues an observable sequence that is terminated by an exception with the next observable sequence.
/// </summary>
/// <typeparam name="TSource">The type of the elements in the source sequence and handler sequence.</typeparam>
/// <param name="first">First observable sequence whose exception (if any) is caught.</param>
/// <param name="second">Second observable sequence used to produce results when an error occurred in the first sequence.</param>
/// <returns>An observable sequence containing the first sequence's elements, followed by the elements of the second sequence in case an exception occurred.</returns>
/// <exception cref="ArgumentNullException"><paramref name="first"/> or <paramref name="second"/> is null.</exception>
public static IObservable<TSource> Catch<TSource>(this IObservable<TSource> first, IObservable<TSource> second)
{
if (first == null)
{
throw new ArgumentNullException(nameof(first));View on GitHub (pinned to 94b5d5ab91)