dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'invoke')
Error message
Value cannot be null. (Parameter 'invoke')
What it means
Add also requires the invocation delegate used to raise the event for each emitted EventPattern; null is rejected because the derived class would have no way to invoke the handler. Fix: pass a non-null invocation delegate alongside the handler.
Solutions
- Supply the delegate that invokes the handler on the event target (e.g. h => target.Event += h style raise).
- Null-check invoke before calling Add.
Example fix
// before
Add(handler, invoke);
// after
Add(handler, invoke ?? (h => { })); // or fix wiring so invoke is real Defensive patterns
Strategy: validation
Validate before calling
if (invoke == null) throw new ArgumentNullException(nameof(invoke));
Type guard
bool CanAdd<TSender, TArgs>(Action<TSender?, TArgs>? invoke) => invoke is not null;
Try / catch
try { Add(handler, invoke); } catch (ArgumentNullException ex) when (ex.ParamName == "invoke") { /* fix wiring and retry */ } Prevention
- Create the raise action together with the handler so neither can be null.
- Avoid reflection-built delegates without a null-check on the build result.
When it happens
Trigger: Calling the protected Add with invoke == null, typically in a derived class whose event-raise action was not initialized or was conditionally created.
Common situations: Custom event adapters where the raise action comes from an optional lambda or reflection-built delegate that failed to build.
Related errors
- Value cannot be null. (Parameter 'handler')
- Value cannot be null. (Parameter 'subscribeAsync')
- Value cannot be null. (Parameter 'observer')
- 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/e767cb7418159875.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/EventPatternSourceBase.cs:109
_invokeHandler = invokeHandler ?? throw new ArgumentNullException(nameof(invokeHandler));
}
/// <summary>
/// Adds the specified event handler, causing a subscription to the underlying source.
/// </summary>
/// <param name="handler">Event handler to add. The same delegate should be passed to the <see cref="Remove(Delegate)"/> operation in order to remove the event handler.</param>
/// <param name="invoke">Invocation delegate to raise the event in the derived class.</param>
/// <exception cref="ArgumentNullException"><paramref name="handler"/> or <paramref name="invoke"/> is <c>null</c>.</exception>
protected void Add(Delegate handler, Action<TSender?, TEventArgs> invoke)
{
if (handler == null)
{
throw new ArgumentNullException(nameof(handler));
}
if (invoke == null)
{
throw new ArgumentNullException(nameof(invoke));
}
var observer = new Observer(this, handler, invoke);
//
// [OK] Use of unsafe Subscribe: non-pretentious wrapper of an observable in an event; exceptions can occur during +=.
//
observer.SetResource(_source.Subscribe(observer));
}
private void Add(Delegate handler, IDisposable disposable)
{
lock (_subscriptions)
{
if (!_subscriptions.TryGetValue(handler, out var l))
{
_subscriptions[handler] = l = new Stack<IDisposable>();
}
View on GitHub (pinned to 94b5d5ab91)