dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'onError')
Error message
Value cannot be null. (Parameter 'onError')
What it means
The AnonymousObserver constructor throws ArgumentNullException when the onError action is null. Rx requires an explicit error handler so exceptions from the sequence are observed rather than silently swallowed; passing null onError is rejected at construction.
Solutions
- Supply a real onError action, e.g. ex => Console.Error.WriteLine(ex)
- If errors can be ignored deliberately, pass a no-op: _ => { }
- Configure/default the error handler before subscribing
Example fix
// before var sub = source.Subscribe(x => Handle(x), null, () => Done()); // after var sub = source.Subscribe(x => Handle(x), ex => Log(ex), () => Done());
Defensive patterns
Strategy: type-guard
Validate before calling
// C#
Action<Exception>? onError = ResolveErrorHandler();
if (onError is null)
onError = ex => Console.Error.WriteLine(ex);
var sub = source.Subscribe(x => Handle(x), onError, () => Done()); Type guard
bool HasErrorHandler(Action<Exception>? a) => a is not null;
Try / catch
try { var sub = source.Subscribe(onNext, onError, onCompleted); }
catch (ArgumentNullException ex) when (ex.ParamName == "onError")
{
// supply a default error logger
} Prevention
- Always pass an error handler — Rx sequences commonly fail
- Default missing loggers to Console.Error.WriteLine
- Avoid passing null positionally in the 3-arg Subscribe overload
When it happens
Trigger: Calling new AnonymousObserver<T>(onNext, null, onCompleted) or source.Subscribe(onNext, onError: null, onCompleted), e.g. source.Subscribe(x => ..., null, () => ...) where a logging/error delegate variable is null.
Common situations: Logging integrations where the error logger is not configured; test scaffolding that only wires onNext and onCompleted; plugin systems where the error handler is optional but the API demands it.
Related errors
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onCompleted')
- observer
- observer
- observer
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/9f91fcb4256f9f67.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/AnonymousObserver.cs:27
/// </summary>
/// <typeparam name="T">The type of the elements in the sequence.</typeparam>
public sealed class AnonymousObserver<T> : ObserverBase<T>
{
private readonly Action<T> _onNext;
private readonly Action<Exception> _onError;
private readonly Action _onCompleted;
/// <summary>
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/>, <see cref="IObserver{T}.OnError(Exception)"/>, and <see cref="IObserver{T}.OnCompleted()"/> actions.
/// </summary>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <param name="onError">Observer's <see cref="IObserver{T}.OnError(Exception)"/> action implementation.</param>
/// <param name="onCompleted">Observer's <see cref="IObserver{T}.OnCompleted()"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> or <paramref name="onError"/> or <paramref name="onCompleted"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext, Action<Exception> onError, Action onCompleted)
{
_onNext = onNext ?? throw new ArgumentNullException(nameof(onNext));
_onError = onError ?? throw new ArgumentNullException(nameof(onError));
_onCompleted = onCompleted ?? throw new ArgumentNullException(nameof(onCompleted));
}
/// <summary>
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/> action.
/// </summary>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <exception cref="ArgumentNullException"><paramref name="onNext"/> is <c>null</c>.</exception>
public AnonymousObserver(Action<T> onNext)
: this(onNext, Stubs.Throw, Stubs.Nop)
{
}
/// <summary>
/// Creates an observer from the specified <see cref="IObserver{T}.OnNext(T)"/> and <see cref="IObserver{T}.OnError(Exception)"/> actions.
/// </summary>
/// <param name="onNext">Observer's <see cref="IObserver{T}.OnNext(T)"/> action implementation.</param>
/// <param name="onError">Observer's <see cref="IObserver{T}.OnError(Exception)"/> action implementation.</param>View on GitHub (pinned to 94b5d5ab91)