dotnet/reactive · error · InvalidOperationException

The add method of an event should take one parameter.

Error message

The add method of an event should take one parameter.

What it means

The event's add accessor must take exactly one parameter (the delegate). GetEventMethods throws InvalidOperationException when addMethod.GetParameters() has a length other than 1, since the metadata violates the CLR event pattern and a handler delegate cannot be constructed.

Solutions

  1. Ensure the event follows the standard CLR event pattern: add(object delegate) with a single delegate parameter
  2. Re-declare the event as 'public event SomeDelegate Name;' and let the compiler generate correct accessors
  3. Inspect addMethod.GetParameters() yourself to diagnose the actual signature

Example fix

// before
// hand-written accessor with extra param
public void add_Tick(EventHandler h, object token) { ... }
// after
public event EventHandler Tick; // compiler-generated add/remove, one parameter each
Defensive patterns

Strategy: validation

Validate before calling

var ev = type.GetEvent(eventName);
var add = ev?.GetAddMethod();
if (add is null || add.GetParameters().Length != 1) throw new NotSupportedException($"Event '{eventName}' add accessor must take exactly one delegate parameter.");

Type guard

static bool HasValidAddSignature(Type t, string name) => t.GetEvent(name)?.GetAddMethod()?.GetParameters().Length == 1;

Prevention

When it happens

Trigger: Reflecting over something that is not a well-formed event (e.g. a method pair mistakenly exposed as an 'event' via custom metadata, or hand-authored IL emitting an add method with extra parameters).

Common situations: Custom reflection-based event emitters, code-weaving/AOP tools rewriting accessor signatures, or passing the wrong EventInfo through a custom wrapper.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs:289

            }
            else
            {
                e = targetType.GetEventEx(eventName, isStatic: false);
                if (e == null)
                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, "Could not find instance event '{0}' on type '{1}'.", eventName, targetType.FullName));
            }

            var addMethod = e.GetAddMethod();
            var removeMethod = e.GetRemoveMethod();

            if (addMethod == null)
                throw new InvalidOperationException("Missing add method on event.");
            if (removeMethod == null)
                throw new InvalidOperationException("Missing remove method on event.");

            var psa = addMethod.GetParameters();
            if (psa.Length != 1)
                throw new InvalidOperationException("The add method of an event should take one parameter.");

            var psr = removeMethod.GetParameters();
            if (psr.Length != 1)
                throw new InvalidOperationException("The remove method of an event should take one parameter.");

            var isWinRT = false;

            if (addMethod.ReturnType != typeof(void))
            {
                isWinRT = true;

                var pet = psr[0];
                if (pet.ParameterType != addMethod.ReturnType)
                    throw new InvalidOperationException("An event should either have add and remove methods that return void or an add method that returns a type compatible with the parameter type of the remove method.");
            }

            var delegateType = psa[0].ParameterType;

View on GitHub (pinned to 94b5d5ab91)