dotnet/reactive · error · InvalidOperationException

Strings_Linq.COULD_NOT_FIND_STATIC_EVENT

Error message

Strings_Linq.COULD_NOT_FIND_STATIC_EVENT

What it means

ReflectionUtils.GetEventMethods resolves an event by name via reflection. When the target is null (static event lookup), it searches public static events on targetType and throws InvalidOperationException 'Could not find static event <name> on <type>' when no such event exists. This powers Observable.FromEventPattern.

Solutions

  1. Verify the event name spelling and that it is declared public static on targetType.
  2. If the event is an instance event, pass the target instance instead of null.
  3. Check targetType.FullName at runtime (print it) to confirm the intended type is being reflected.

Example fix

// before
Observable.FromEventPattern(null, "Changed", typeof(Config)); // event is instance-level
// after
var cfg = new Config();
Observable.FromEventPattern(cfg, "Changed", typeof(Config));
Defensive patterns

Strategy: validation

Validate before calling

var evt = targetType.GetEvent(eventName, BindingFlags.Public | BindingFlags.Static);
if (evt == null) throw new ArgumentException($"Static event '{eventName}' not found on {targetType.FullName}");
Observable.FromEventPattern(null, eventName, targetType);

Type guard

static bool HasStaticEvent(Type t, string name) => t.GetEvent(name, BindingFlags.Public | BindingFlags.Static) != null;

Try / catch

try { Observable.FromEventPattern(null, eventName, targetType); } catch (InvalidOperationException ex) when (ex.Message.Contains("static event")) { /* correct name or target */ }

Prevention

When it happens

Trigger: Observable.FromEventPattern(target: null, eventName, targetType) with an eventName that is not a public static event on targetType, or a misspelled event name.

Common situations: Typos in event name strings; event exists but is instance-level while null target forces static lookup; event declared non-public; type moved/renamed the event in a newer version.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/5f5b0dccbc90e49d. Report an issue: GitHub.

Appendix: source

Thrown at Rx.NET/Source/src/System.Reactive/Internal/ReflectionUtils.cs:33

            return (TDelegate)(object)method.CreateDelegate(typeof(TDelegate), o);
        }

        public static Delegate CreateDelegate(Type delegateType, object o, MethodInfo method)
        {
            return method.CreateDelegate(delegateType, o);
        }

#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)

View on GitHub (pinned to 94b5d5ab91)