dotnet/reactive · error · InvalidOperationException
Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE
Error message
Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE
What it means
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.
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.
Example fix
// before Observable.FromEventPattern<object, EventArgs>(textBox, nameof(textBox.KeyDown)); // after Observable.FromEventPattern<object, KeyEventArgs>(textBox, nameof(textBox.KeyDown));
Defensive patterns
Strategy: validation
Validate before calling
var invoke = delegateType.GetMethod("Invoke");
var argsType = invoke?.GetParameters().ElementAtOrDefault(1)?.ParameterType;
if (argsType == null || !argsType.IsAssignableFrom(typeof(TEventArgs)))
throw new ArgumentException($"TEventArgs must match the delegate's args parameter ({argsType?.Name})"); Try / catch
try
{
var src = Observable.FromEventPattern<TSender, TEventArgs>(target, eventName);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("args"))
{
// retry with the delegate's actual args type
} Prevention
- 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.
When it happens
Trigger: Calling FromEventPattern<S, MouseEventHandlerArgs>(...) where the delegate's second parameter is, e.g., KeyEventArgs or EventArgs, not the supplied TEventArgs.
Common situations: Guessing the TEventArgs type instead of reading the delegate signature; reusing generic arguments across events; events using custom EventArgs-derived types.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE
- The event arguments parameter of the event is not…
- The sender parameter of the event is not assignable to
- addHandler
- addHandler
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/11013a1ad9ad5a8d.
Report an issue: GitHub.
Appendix: source
Thrown at Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs:87
delegateType = psa[0].ParameterType;
var invokeMethod = delegateType.GetMethod("Invoke")!; // NB: Delegates always have an Invoke method.
var parameters = invokeMethod.GetParameters();
if (parameters.Length != 2)
{
throw new InvalidOperationException(Strings_Linq.EVENT_PATTERN_REQUIRES_TWO_PARAMETERS);
}
if (!typeof(TSender).IsAssignableFrom(parameters[0].ParameterType))
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_SENDER_NOT_ASSIGNABLE, typeof(TSender).FullName));
}
if (!typeof(TEventArgs).IsAssignableFrom(parameters[1].ParameterType))
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Strings_Linq.EVENT_ARGS_NOT_ASSIGNABLE, typeof(TEventArgs).FullName));
}
if (invokeMethod.ReturnType != typeof(void))
{
throw new InvalidOperationException(Strings_Linq.EVENT_MUST_RETURN_VOID);
}
}
/// <summary>
/// Determine whether a type represents a WinRT event registration token
/// (https://learn.microsoft.com/en-us/uwp/api/windows.foundation.eventregistrationtoken).
/// </summary>
/// <param name="t">The type to check.</param>
/// <returns>True if this represents a WinRT event registration token</returns>
/// <remarks>
/// <para>
/// We used to perform a simple comparison with typeof(EventRegistrationToken), but the
/// introduction of C#/WinRT has made this problematic. Before C#/WinRT, the .NETView on GitHub (pinned to 94b5d5ab91)