dotnet/reactive · error · ArgumentNullException
ArgumentNullException(nameof(onCompleted))
Error message
ArgumentNullException(nameof(onCompleted))
What it means
This Do overload validates the onError callback passed as a side-effect observer action; null would make the tap unable to react to errors. The exception is thrown eagerly at operator-assembly time, not at subscription time. Fix: provide a non-null Action<Exception>, or use the Do overload that omits the error handler.
Solutions
- Pass a real Action, using a no-op () => { } if no work is needed
- Default the handler before composition: handler ?? (() => { })
- Fix the configuration/DI wiring that should have provided the handler
Example fix
// before
Action onCompleted = null;
var res = src.Do(onCompleted); // throws
// after
var res = src.Do(onCompleted ?? (() => { })); Defensive patterns
Strategy: validation
Validate before calling
if (onCompleted is null) onCompleted = () => { };
var res = source.Do(onCompleted); Type guard
static bool IsValidHandler(Action h) => h is not null;
Try / catch
try { var res = source.Do(onCompleted); }
catch (ArgumentNullException ex) when (ex.ParamName == "onCompleted") { /* fall back to no-op */ } Prevention
- Initialize delegate fields with no-op defaults rather than null
- Use handler ?? (() => { }) at call sites
- Verify configuration wiring assigns completion handlers
- Enable nullable reference types
When it happens
Trigger: Calling source.Do(onCompleted) with a null Action, e.g. an unassigned completion-handler field or a null method-group conversion failure.
Common situations: Optional teardown callbacks that default to null; forwarding an uninitialized parameter; configuration wiring that skipped the handler.
Related errors
- ArgumentNullException(nameof(onError))
- Value cannot be null. (Parameter 'onCompletedAsync')
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
- nameof(finallyAction)
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/a18922d7876d4664.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Do.cs:55
public static IAsyncObservable<TSource> Do<TSource>(this IAsyncObservable<TSource> source, Action<Exception> onError)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onError == null)
throw new ArgumentNullException(nameof(onError));
return Create(
source,
onError,
static (source, onError, target) => source.SubscribeSafeAsync(AsyncObserver.Do(target, onError)));
}
public static IAsyncObservable<TSource> Do<TSource>(this IAsyncObservable<TSource> source, Action onCompleted)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onCompleted == null)
throw new ArgumentNullException(nameof(onCompleted));
return Create(
source,
onCompleted,
static (source, onCompleted, target) => source.SubscribeSafeAsync(AsyncObserver.Do(target, onCompleted)));
}
public static IAsyncObservable<TSource> Do<TSource>(this IAsyncObservable<TSource> source, Action<TSource> onNext, Action<Exception> onError, Action onCompleted)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onNext == null)
throw new ArgumentNullException(nameof(onNext));
if (onError == null)
throw new ArgumentNullException(nameof(onError));
if (onCompleted == null)
throw new ArgumentNullException(nameof(onCompleted));
View on GitHub (pinned to 94b5d5ab91)