dotnet/reactive · error · ArgumentNullException
addHandler
Error message
addHandler
What it means
FromEventPattern(addHandler, removeHandler, scheduler) validates arguments in order; this error means addHandler (an Action<EventHandler>) was null. Since FromEventPattern forwards to FromEvent<EventHandler, object, EventArgs>, the null addHandler makes the event subscription impossible and the guard throws ArgumentNullException with ParamName "addHandler".
Solutions
- Pass the event's add accessor: h => src.Clicked += h.
- Use the string/EventInfo-based FromEventPattern overloads when wiring via reflection, which resolve accessors for you.
- Verify add/remove arguments are in the right order and the source object is initialized.
Example fix
// before var sub = AsyncRx.Observable.FromEventPattern(null, h => src.Clicked -= h); // after var sub = AsyncRx.Observable.FromEventPattern(h => src.Clicked += h, h => src.Clicked -= h);
Defensive patterns
Strategy: validation
Validate before calling
if (addHandler == null || removeHandler == null) throw new ArgumentException("Both addHandler and removeHandler are required, e.g. h => src.Clicked += h / h => src.Clicked -= h"); Type guard
bool CanSubscribePattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler) => addHandler != null && removeHandler != null;
Try / catch
try { var sub = FromEventPattern(add, remove); }
catch (ArgumentNullException ex) when (ex.ParamName == "addHandler") { /* check argument order and source initialization */ } Prevention
- FromEventPattern expects EventHandler delegates; pass += accessor first, -= accessor second.
- Prefer the string-name FromEventPattern overloads when events are resolved by reflection.
- Verify the event source object exists before constructing accessor lambdas.
When it happens
Trigger: Calling FromEventPattern(null, removeHandler) or FromEventPattern(null, removeHandler, scheduler), e.g. FromEventPattern(null, h => src.Event -= h).
Common situations: Reflection overloads (FromEventPattern(name)) resolved elsewhere but here wiring delegates directly from a lookup table where the add entry is missing; swapping add/remove by mistake; event source obtained from an uninitialized control so the accessor lambda was never built.
Related errors
- conversion
- nameof(removeHandler)
- Value cannot be null. (Parameter 'predicate')
- Value cannot be null. (Parameter 'observer')
- Value cannot be null. (Parameter 'source')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/54bd4496cbed9a15.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs:21
// See the LICENSE file in the project root for more information.
using System.Globalization;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
namespace System.Reactive.Linq
{
public partial class AsyncObservable
{
public static IAsyncObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler) => FromEventPattern(addHandler, removeHandler, GetSchedulerForCurrentContext());
public static IAsyncObservable<EventPattern<object>> FromEventPattern(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, IAsyncScheduler scheduler)
{
if (addHandler == null)
throw new ArgumentNullException(nameof(addHandler));
if (removeHandler == null)
throw new ArgumentNullException(nameof(removeHandler));
if (scheduler == null)
throw new ArgumentNullException(nameof(scheduler));
return FromEvent<EventHandler, object, EventArgs>(
action => new EventHandler((o, e) => action(o, e)),
addHandler,
removeHandler,
scheduler).Select(t => new EventPattern<object>(t.arg1, t.arg2));
}
public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler) => FromEventPattern<TDelegate, TEventArgs>(addHandler, removeHandler, GetSchedulerForCurrentContext());
public static IAsyncObservable<EventPattern<TEventArgs>> FromEventPattern<TDelegate, TEventArgs>(Action<TDelegate> addHandler, Action<TDelegate> removeHandler, IAsyncScheduler scheduler)
{
if (addHandler == null)
throw new ArgumentNullException(nameof(addHandler));View on GitHub (pinned to 94b5d5ab91)