dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'handler')
Error message
Value cannot be null. (Parameter 'handler')
What it means
Observer.ToObserver<T> converts an Action<Notification<T>> into an IObserver<T>. It throws ArgumentNullException when the handler delegate is null, because there is no sensible observer to construct without it.
Solutions
- Pass a non-null Action<Notification<T>> handling OnNext/OnError/OnCompleted
- Null-check the delegate before calling ToObserver
- Use Notification.CreateOnNext etc. inside a concrete handler implementation
Example fix
// before
var obs = source.ToObserver(null);
// after
var obs = source.ToObserver(n => { switch (n.Kind) { case NotificationKind.OnNext: Console.WriteLine(n.Value); break; } }); Defensive patterns
Strategy: type-guard
Validate before calling
if (handler == null) throw new InvalidOperationException("handler must be provided before calling ToObserver"); Type guard
static bool IsValidHandler<T>(Action<Notification<T>>? h) => h is not null;
Try / catch
try { var obs = handler.ToObserver(); } catch (ArgumentNullException ex) when (ex.ParamName == "handler") { obs = Observer.Create<T>(_ => { }, _ => { }, () => { }); } Prevention
- Null-check delegates before passing to Rx extension methods
- Avoid passing results of dictionary/reflection lookups directly as handlers
- Use non-nullable delegate types (Action<Notification<T>> = default!) sparingly and initialize early
When it happens
Trigger: Calling handler: null with Observable.ToObserver<T>(null) or extension usage source.ToObserver((Action<Notification<int>>)null!).
Common situations: Passing a method group that failed to bind, a conditional result of a lookup that returned null, or refactoring that left a null lambda.
Related errors
- observer
- observer
- Value cannot be null. (Parameter 'onNext')
- Value cannot be null. (Parameter 'onError')
- Value cannot be null. (Parameter 'onCompleted')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/b4099beab0614b28.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Observer.Extensions.cs:26
namespace System.Reactive
{
/// <summary>
/// Provides a set of static methods for creating observers.
/// </summary>
public static class Observer
{
/// <summary>
/// Creates an observer from a notification callback.
/// </summary>
/// <typeparam name="T">The type of the elements received by the observer.</typeparam>
/// <param name="handler">Action that handles a notification.</param>
/// <returns>The observer object that invokes the specified handler using a notification corresponding to each message it receives.</returns>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> is null.</exception>
public static IObserver<T> ToObserver<T>(this Action<Notification<T>> handler)
{
if (handler == null)
{
throw new ArgumentNullException(nameof(handler));
}
return new AnonymousObserver<T>(
x => handler(Notification.CreateOnNext(x)),
exception => handler(Notification.CreateOnError<T>(exception)),
() => handler(Notification.CreateOnCompleted<T>())
);
}
/// <summary>
/// Creates a notification callback from an observer.
/// </summary>
/// <typeparam name="T">The type of the elements received by the observer.</typeparam>
/// <param name="observer">Observer object.</param>
/// <returns>The action that forwards its input notification to the underlying observer.</returns>
/// <exception cref="ArgumentNullException"><paramref name="observer"/> is null.</exception>
[Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Notifier", Justification = "Backward compat.")]
public static Action<Notification<T>> ToNotifier<T>(this IObserver<T> observer)View on GitHub (pinned to 94b5d5ab91)