{"record":{"id":"78b62f99fc621449","repo":"stride3d/stride","slug":"the-given-event-info-must-have-exactly-two-parameters","errorCode":null,"errorMessage":"The given event info must have exactly two parameters.","messagePattern":"The given event info must have exactly two parameters\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/presentation/Stride.Core.Presentation.Wpf/Core/AnonymousEventHandler.cs","lineNumber":23,"sourceCode":"using System.Reflection;\nusing Stride.Core.Annotations;\n\nnamespace Stride.Core.Presentation.Core\n{\n    public class AnonymousEventHandler\n    {\n        protected Action Action;\n        private Delegate eventHandler;\n        private EventInfo eventInfo;\n        private object target;\n\n        [NotNull]\n        public static AnonymousEventHandler RegisterEventHandler([NotNull] EventInfo eventInfo, object target, Action handler)\n        {\n            var parameterInfos = eventInfo.EventHandlerType.GetMethod(\"Invoke\").GetParameters();\n\n            if (parameterInfos.Length != 2)\n                throw new ArgumentException(\"The given event info must have exactly two parameters.\");\n\n            var argumentType = parameterInfos.Skip(1).First().ParameterType;\n            var type = typeof(AnonymousEventHandler<>).MakeGenericType(argumentType);\n\n            var method = type.GetMethod(\"Handler\");\n            var anonymousHandler = (AnonymousEventHandler)Activator.CreateInstance(type);\n            anonymousHandler.Action = handler;\n            anonymousHandler.eventHandler = Delegate.CreateDelegate(eventInfo.EventHandlerType, anonymousHandler, method);\n            anonymousHandler.eventInfo = eventInfo;\n            anonymousHandler.target = target;\n            eventInfo.AddEventHandler(target, anonymousHandler.eventHandler);\n\n            return anonymousHandler;\n        }\n\n        public static void UnregisterEventHandler([NotNull] AnonymousEventHandler handler)\n        {\n            handler.eventInfo.RemoveEventHandler(handler.target, handler.eventHandler);","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/presentation/Stride.Core.Presentation.Wpf/Core/AnonymousEventHandler.cs#L5-L41","documentation":"AnonymousEventHandler.RegisterEventHandler dynamically subscribes a handler to an arbitrary event via reflection. It expects the classic .NET event pattern of exactly two parameters (sender, args); if the EventInfo's handler delegate has any other parameter count, it throws ArgumentException because it cannot construct the generic AnonymousEventHandler<TArgs>.","triggerScenarios":"Calling RegisterEventHandler with an EventInfo whose EventHandlerType's Invoke method has a parameter count other than 2 — e.g. custom delegates like delegate void Callback(int code) or parameterless/hand-rolled delegate events.","commonSituations":"Reflective wiring of events on third-party or COM/interop objects that use non-standard delegates; hooking custom events that deviate from EventHandler<T> convention.","solutions":["Ensure the event uses a standard two-parameter delegate (EventHandler, EventHandler<TEventArgs>, or equivalent (object, TArgs) signature).","Subscribe manually with a matching custom delegate instead of using RegisterEventHandler.","Change the event's delegate type on the declaring type to follow the standard .NET event pattern.","Validate parameterInfos.Length == 2 before calling and fall back to a manual subscription."],"exampleFix":"// before (non-standard delegate)\npublic event Action<int> Progress; // 1 parameter\n// after\npublic event EventHandler<int> Progress; // (object sender, int e)","handlingStrategy":"validation","validationCode":"var invoke = eventInfo.EventHandlerType.GetMethod(\"Invoke\");\nif (invoke.GetParameters().Length != 2)\n    throw new NotSupportedException($\"Event {eventInfo.Name} does not follow the (sender, args) pattern\");\nAnonymousEventHandler.RegisterEventHandler(eventInfo, target, handler);","typeGuard":"bool IsStandardEventPattern(EventInfo e) =>\n    e.EventHandlerType.GetMethod(\"Invoke\").GetParameters().Length == 2;","tryCatchPattern":"try { AnonymousEventHandler.RegisterEventHandler(eventInfo, target, handler); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"exactly two parameters\")) { /* subscribe manually with a delegate matching the custom signature */ }","preventionTips":["Only register events declared with EventHandler/EventHandler<T> or equivalent two-parameter delegates.","Check parameter count via reflection before dynamic registration.","For custom delegate events, write explicit handlers instead of generic registration."],"tags":["reflection","events","argument"],"backgroundTag":"invalid-argument-value","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}