dotnet/reactive · error · InvalidOperationException
Strings_Linq.EVENT_MISSING_ADD_METHOD
Error message
Strings_Linq.EVENT_MISSING_ADD_METHOD
What it means
After locating the EventInfo, GetEventMethods fetches its add accessor; if the event has no public add method (e.g. custom event accessors where add is private or the event is abstract-in-metadata), it throws InvalidOperationException 'Event missing add method'. FromEventPattern needs add/remove to subscribe.
Solutions
- Make the event's add accessor public, or subscribe through the public surface instead.
- Use the delegate-based FromEventPattern overloads (explicit addHandler/removeHandler lambdas) that call the accessors you specify.
- If subscribing from another assembly, ensure the event's accessors are at least InternalsVisibleTo-visible and adjust to public.
Example fix
// before
private event EventHandler E { add { } remove { } }
// after
public event EventHandler E { add { } remove { } } Defensive patterns
Strategy: validation
Validate before calling
var evt = targetType.GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance);
if (evt?.GetAddMethod() == null) throw new NotSupportedException($"Event '{eventName}' has no public add accessor"); Type guard
static bool HasPublicAdd(Type t, string name) => t.GetEvent(name)?.GetAddMethod() != null;
Try / catch
try { Observable.FromEventPattern(target, eventName, targetType); } catch (InvalidOperationException ex) when (ex.Message.Contains("add method")) { /* use explicit add/remove overloads */ } Prevention
- Declare events with standard public accessors.
- Check EventInfo.GetAddMethod() != null before reflection subscription.
- Use FromEventPattern(handler => target.Ev += handler, handler => target.Ev -= handler) to bypass accessor discovery.
When it happens
Trigger: FromEventPattern against an event whose add accessor is non-public or missing — custom add/remove accessors with private add, events defined in non-public interfaces, or platform events with restricted accessors.
Common situations: Events with custom accessors (add private, remove public); COM/WinRT interop events; events bound in Reflection-only contexts where accessors aren't resolvable.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- Strings_Linq.EVENT_MISSING_REMOVE_METHOD
- Strings_Linq.COULD_NOT_FIND_INSTANCE_EVENT
- Strings_Linq.COULD_NOT_FIND_STATIC_EVENT
- Strings_Linq.EVENT_ADD_METHOD_SHOULD_TAKE_ONE_PARAMETER
- An event should either have add and remove methods that…
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/7c960f88869ad49a.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs:41
#if HAS_TRIMMABILITY_ATTRIBUTES
[RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]
#endif
public static void GetEventMethods<TSender, TEventArgs>(Type targetType, object? target, string eventName, out MethodInfo addMethod, out MethodInfo removeMethod, out Type delegateType, out bool isWinRT)
{
EventInfo? e;
if (target == null)
{
e = targetType.GetEvent(eventName, BindingFlags.Public | BindingFlags.Static)
?? throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_STATIC_EVENT, eventName, targetType.FullName));
}
else
{
e = targetType.GetEvent(eventName, BindingFlags.Public | BindingFlags.Instance)
?? throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.COULD_NOT_FIND_INSTANCE_EVENT, eventName, targetType.FullName));
}
addMethod = e.GetAddMethod() ?? throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_ADD_METHOD);
removeMethod = e.GetRemoveMethod() ?? throw new InvalidOperationException(Strings_Linq.EVENT_MISSING_REMOVE_METHOD);
var psa = addMethod.GetParameters();
if (psa.Length != 1)
{
throw new InvalidOperationException(Strings_Linq.EVENT_ADD_METHOD_SHOULD_TAKE_ONE_PARAMETER);
}
var psr = removeMethod.GetParameters();
if (psr.Length != 1)
{
throw new InvalidOperationException(Strings_Linq.EVENT_REMOVE_METHOD_SHOULD_TAKE_ONE_PARAMETER);
}
isWinRT = false;
if (IsWinRTEventRegistrationTokenType(addMethod.ReturnType))
{View on GitHub (pinned to 94b5d5ab91)