dotnet/reactive · error · ArgumentNullException

Value cannot be null. (Parameter 'target')

Error message

Value cannot be null. (Parameter 'target')

What it means

The reflection-based overload Observable.FromEventPattern(object target, string eventName) throws ArgumentNullException when target is null. Rx uses the target instance to reflect over its events by name, so a null instance makes the operation impossible; it fails fast before any reflection work.

Solutions

  1. Ensure the event source instance is created/assigned before building the observable, e.g. after InitializeComponent().
  2. Pass the correct target object that actually owns the event.
  3. If the source may legitimately be absent, guard with a null check and return Observable.Empty<EventPattern<object>>() or throw a descriptive error in your own code.
  4. Verify DI/factory wiring so the target dependency is provided.

Example fix

// before
Button btn = null;
var clicks = Observable.FromEventPattern(btn, "Click");
// after
btn = this.myButton; // ensure assigned
var clicks = Observable.FromEventPattern(btn, "Click");
Defensive patterns

Strategy: validation

Validate before calling

if (target == null) throw new InvalidOperationException("Event source not initialized");

Type guard

bool CanSubscribeFrom(object target, string eventName) => target != null && !string.IsNullOrEmpty(eventName);

Try / catch

try { var xs = Observable.FromEventPattern(target, eventName); }
catch (ArgumentNullException ex) when (ex.ParamName == "target") { /* fix source initialization */ }

Prevention

When it happens

Trigger: Calling Observable.FromEventPattern(someObject, "EventName") with a null target reference while eventName is non-null (target check at line 549 precedes the eventName check at 554).

Common situations: A control or service field that is null because it was never assigned or injected (e.g. UI control accessed before InitializeComponent or after Dispose); a factory method that returned null; reflection-resolved object that didn't exist.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/cf383d99529345d3. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Linq/Observable.Events.cs:549

        /// <para>
        /// If no SynchronizationContext is present at the point of calling FromEventPattern, add and remove handler invocations are made synchronously on the thread
        /// making the Subscribe or Dispose call, respectively.
        /// </para>
        /// <para>
        /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so
        /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions
        /// more concise and easier to understand.
        /// </para>
        /// </remarks>
        /// <seealso cref="ToEventPattern"/>
#if HAS_TRIMMABILITY_ATTRIBUTES
        [RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
#endif
        public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName)
        {
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }

            if (eventName == null)
            {
                throw new ArgumentNullException(nameof(eventName));
            }

            return s_impl.FromEventPattern(target, eventName);
        }

        /// <summary>
        /// Converts an instance .NET event, conforming to the standard .NET event pattern with an <see cref="EventArgs"/> parameter, to an observable sequence.
        /// Each event invocation is surfaced through an OnNext message in the resulting sequence.
        /// Reflection is used to discover the event based on the target object type and the specified event name.
        /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.
        /// </summary>
        /// <param name="target">Object instance that exposes the event to convert.</param>
        /// <param name="eventName">Name of the event to convert.</param>

View on GitHub (pinned to 94b5d5ab91)