dotnet/reactive · error · ArgumentNullException
onCompleted
Error message
onCompleted
What it means
The Subscribe(source, onNext, onCompleted) overload throws ArgumentNullException with ParamName "onCompleted" when the onCompleted Action is null. Rx validates it eagerly since AnonymousObserver needs a concrete completion handler; internally the error slot is filled with Stubs.Throw.
Solutions
- Pass a non-null onCompleted delegate, e.g. () => { } if completion is irrelevant.
- Use the onNext+onError overload if completion handling is truly unnecessary (it stubs onCompleted for you).
- Ensure the completion callback is initialized before subscribing.
Example fix
// before
source.Subscribe(x => Handle(x), null); // ArgumentNullException: onCompleted
// after
source.Subscribe(x => Handle(x), () => Console.WriteLine("done")); Defensive patterns
Strategy: validation
Validate before calling
if (onCompleted is null) onCompleted = () => { }; // or use Subscribe(onNext, onError) overload Type guard
static bool HasHandlers<T>(Action<T> onNext, Action onCompleted) => onNext is not null && onCompleted is not null;
Try / catch
try { disposable = source.Subscribe(onNext, onCompleted); }
catch (ArgumentNullException ex) when (ex.ParamName == "onCompleted") { /* supply no-op completion handler */ } Prevention
- Remember Rx delegates are not optional parameters; never pass null in place of a handler.
- Use Subscribe(onNext, onError) when completion handling is not needed.
- Default completion callbacks to no-op lambdas in shared subscription helpers.
When it happens
Trigger: Calling source.Subscribe(onNext, null) intending to skip completion handling, or passing an Action variable that was never assigned.
Common situations: Assuming optional trailing arguments may be null (they cannot, despite C# optional-parameter habits); refactoring that removed the completion lambda but kept the call; dynamic handler registration failing to produce the action.
Related errors
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
- Value cannot be null. (Parameter 'onCompleted')
- observer
- onError
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/20531a5d4566c744.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Observable.Extensions.cs:121
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <param name="onCompleted">Action to invoke upon graceful termination of the observable sequence.</param>
/// <returns><see cref="IDisposable"/> object used to unsubscribe from the observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onCompleted"/> is <c>null</c>.</exception>
public static IDisposable Subscribe<T>(this IObservable<T> source, Action<T> onNext, Action onCompleted)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (onNext == null)
{
throw new ArgumentNullException(nameof(onNext));
}
if (onCompleted == null)
{
throw new ArgumentNullException(nameof(onCompleted));
}
//
// [OK] Use of unsafe Subscribe: non-pretentious constructor for an observer; this overload is not to be used internally.
//
return source.Subscribe/*Unsafe*/(new AnonymousObserver<T>(onNext, Stubs.Throw, onCompleted));
}
/// <summary>
/// Subscribes an element handler, an exception handler, and a completion handler to an observable sequence.
/// </summary>
/// <typeparam name="T">The type of the elements in the source sequence.</typeparam>
/// <param name="source">Observable sequence to subscribe to.</param>
/// <param name="onNext">Action to invoke for each element in the observable sequence.</param>
/// <param name="onError">Action to invoke upon exceptional termination of the observable sequence.</param>
/// <param name="onCompleted">Action to invoke upon graceful termination of the observable sequence.</param>
/// <returns><see cref="IDisposable"/> object used to unsubscribe from the observable sequence.</returns>
/// <exception cref="ArgumentNullException"><paramref name="source"/> or <paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is <c>null</c>.</exception>View on GitHub (pinned to 94b5d5ab91)