{"record":{"id":"11013a1ad9ad5a8d","repo":"dotnet/reactive","slug":"strings-linq-event-args-not-assignable","errorCode":null,"errorMessage":"Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE","messagePattern":"Strings_Linq\\.EVENT_ARGS_NOT_ASSIGNABLE","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs","lineNumber":87,"sourceCode":"            delegateType = psa[0].ParameterType;\n\n            var invokeMethod = delegateType.GetMethod(\"Invoke\")!; // NB: Delegates always have an Invoke method.\n\n            var parameters = invokeMethod.GetParameters();\n\n            if (parameters.Length != 2)\n            {\n                throw new InvalidOperationException(Strings_Linq.EVENT_PATTERN_REQUIRES_TWO_PARAMETERS);\n            }\n\n            if (!typeof(TSender).IsAssignableFrom(parameters[0].ParameterType))\n            {\n                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE, typeof(TSender).FullName));\n            }\n\n            if (!typeof(TEventArgs).IsAssignableFrom(parameters[1].ParameterType))\n            {\n                throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE, typeof(TEventArgs).FullName));\n            }\n\n            if (invokeMethod.ReturnType != typeof(void))\n            {\n                throw new InvalidOperationException(Strings_Linq.EVENT_MUST_RETURN_VOID);\n            }\n        }\n\n        /// <summary>\n        /// Determine whether a type represents a WinRT event registration token\n        /// (https://learn.microsoft.com/en-us/uwp/api/windows.foundation.eventregistrationtoken).\n        /// </summary>\n        /// <param name=\"t\">The type to check.</param>\n        /// <returns>True if this represents a WinRT event registration token</returns>\n        /// <remarks>\n        /// <para>\n        /// We used to perform a simple comparison with typeof(EventRegistrationToken), but the\n        /// introduction of C#/WinRT has made this problematic. Before C#/WinRT, the .NET","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs#L69-L105","documentation":"FromEventPattern<TSender, TEventArgs> requires the event delegate's second parameter (the event-args parameter) to be assignable from TEventArgs. GetEventMethods throws InvalidOperationException when TEventArgs is not compatible with the delegate's args parameter type.","triggerScenarios":"Calling FromEventPattern<S, MouseEventHandlerArgs>(...) where the delegate's second parameter is, e.g., KeyEventArgs or EventArgs, not the supplied TEventArgs.","commonSituations":"Guessing the TEventArgs type instead of reading the delegate signature; reusing generic arguments across events; events using custom EventArgs-derived types.","solutions":["Set TEventArgs to the exact (or assignable-from) type used by the delegate, e.g. KeyEventArgs for KeyboardEventHandler.","Inspect the delegate's Invoke signature to confirm the second parameter type before writing the call.","Use the string-based FromEventPattern overloads that infer the args type."],"exampleFix":"// before\nObservable.FromEventPattern<object, EventArgs>(textBox, nameof(textBox.KeyDown));\n// after\nObservable.FromEventPattern<object, KeyEventArgs>(textBox, nameof(textBox.KeyDown));","handlingStrategy":"validation","validationCode":"var invoke = delegateType.GetMethod(\"Invoke\");\nvar argsType = invoke?.GetParameters().ElementAtOrDefault(1)?.ParameterType;\nif (argsType == null || !argsType.IsAssignableFrom(typeof(TEventArgs)))\n    throw new ArgumentException($\"TEventArgs must match the delegate's args parameter ({argsType?.Name})\");","typeGuard":null,"tryCatchPattern":"try\n{\n    var src = Observable.FromEventPattern<TSender, TEventArgs>(target, eventName);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"args\"))\n{\n    // retry with the delegate's actual args type\n}","preventionTips":["Use the exact EventArgs-derived type declared by the delegate as TEventArgs.","Hover/inspect the delegate (e.g. KeyEventHandler -> KeyEventArgs) before writing generics.","Consider the non-generic FromEventPattern overloads to avoid mismatches."],"tags":["generics","events","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}