{"record":{"id":"9b166a5f84fae8e4","repo":"dotnet/reactive","slug":"missing-add-method-on-event","errorCode":null,"errorMessage":"Missing add method on event.","messagePattern":"Missing add method on event\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs","lineNumber":283,"sourceCode":"\n            if (target == null)\n            {\n                e = targetType.GetEventEx(eventName, isStatic: true);\n                if (e == null)\n                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, \"Could not find static event '{0}' on type '{1}'.\", eventName, targetType.FullName));\n            }\n            else\n            {\n                e = targetType.GetEventEx(eventName, isStatic: false);\n                if (e == null)\n                    throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, \"Could not find instance event '{0}' on type '{1}'.\", eventName, targetType.FullName));\n            }\n\n            var addMethod = e.GetAddMethod();\n            var removeMethod = e.GetRemoveMethod();\n\n            if (addMethod == null)\n                throw new InvalidOperationException(\"Missing add method on event.\");\n            if (removeMethod == null)\n                throw new InvalidOperationException(\"Missing remove method on event.\");\n\n            var psa = addMethod.GetParameters();\n            if (psa.Length != 1)\n                throw new InvalidOperationException(\"The add method of an event should take one parameter.\");\n\n            var psr = removeMethod.GetParameters();\n            if (psr.Length != 1)\n                throw new InvalidOperationException(\"The remove method of an event should take one parameter.\");\n\n            var isWinRT = false;\n\n            if (addMethod.ReturnType != typeof(void))\n            {\n                isWinRT = true;\n\n                var pet = psr[0];","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/FromEventPattern.cs#L265-L301","documentation":"The located EventInfo has no accessible add accessor (GetAddMethod() returned null), so the library cannot subscribe to it and throws InvalidOperationException. An event without an add method cannot have a handler attached via reflection.","triggerScenarios":"Reflecting over an event whose add accessor is non-public, abstract, or otherwise unavailable to the library (e.g. an explicitly implemented interface event or a compiler-generated event with restricted accessors).","commonSituations":"Events declared on internal/explicit interface implementations, events from obfuscated or trimmed assemblies (linker removed the accessor), or platform-projection events with unusual metadata.","solutions":["Subscribe via a public event with standard add/remove accessors","Use the delegate-based FromEvent overload with explicit addHandler/removeHandler delegates referencing the accessors directly","Make the add accessor public (or use BindingFlags-friendly accessibility) if you control the type"],"exampleFix":"// before\nvar obs = AsyncObservable.FromEventPattern<object, EventArgs>(type, \"HiddenEvent\"); // explicit interface event\n// after\nIFoo f = GetFoo();\nvar obs = AsyncObservable.FromEvent<EventHandler, EventArgs>(\n    h => f.HiddenEvent += h, h => f.HiddenEvent -= h);","handlingStrategy":"validation","validationCode":"var ev = type.GetEvent(eventName);\nif (ev?.GetAddMethod() is null) throw new NotSupportedException($\"Event '{eventName}' has no accessible add accessor.\");","typeGuard":"static bool HasAddAccessor(Type t, string name) => t.GetEvent(name)?.GetAddMethod() is not null;","tryCatchPattern":"try { var obs = AsyncObservable.FromEventPattern<TSender, TEventArgs>(target, eventName); }\ncatch (InvalidOperationException ex) { // fall back to delegate-based FromEvent with explicit handlers\n  log.LogWarning(ex, \"No add accessor for {Event}; using manual subscription\", eventName); }","preventionTips":["Stick to compiler-generated events with public accessors","Check linker/trimmer settings that may strip accessors","Prefer FromEvent(addHandler, removeHandler) for unusual events"],"tags":["csharp","reflection","event-accessors","invalid-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}