{"record":{"id":"1f32048c0d535a0d","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-eventname","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'eventName')","messagePattern":"Value cannot be null\\. \\(Parameter 'eventName'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Events.cs","lineNumber":554,"sourceCode":"        /// It's recommended to lift FromEventPattern calls outside event stream query expressions due to the free-threaded nature of Reactive Extensions. Doing so\n        /// makes the captured SynchronizationContext predictable. This best practice also reduces clutter of bridging code inside queries, making the query expressions\n        /// more concise and easier to understand.\n        /// </para>\n        /// </remarks>\n        /// <seealso cref=\"ToEventPattern\"/>\n#if HAS_TRIMMABILITY_ATTRIBUTES\n        [RequiresUnreferencedCode(Constants_Core.EventReflectionTrimIncompatibilityMessage)]\n#endif\n        public static IObservable<EventPattern<object>> FromEventPattern(object target, string eventName)\n        {\n            if (target == null)\n            {\n                throw new ArgumentNullException(nameof(target));\n            }\n\n            if (eventName == null)\n            {\n                throw new ArgumentNullException(nameof(eventName));\n            }\n\n            return s_impl.FromEventPattern(target, eventName);\n        }\n\n        /// <summary>\n        /// Converts an instance .NET event, conforming to the standard .NET event pattern with an <see cref=\"EventArgs\"/> parameter, to an observable sequence.\n        /// Each event invocation is surfaced through an OnNext message in the resulting sequence.\n        /// Reflection is used to discover the event based on the target object type and the specified event name.\n        /// For conversion of events that don't conform to the standard .NET event pattern, use any of the FromEvent overloads instead.\n        /// </summary>\n        /// <param name=\"target\">Object instance that exposes the event to convert.</param>\n        /// <param name=\"eventName\">Name of the event to convert.</param>\n        /// <param name=\"scheduler\">The scheduler to run the add and remove event handler logic on.</param>\n        /// <returns>The observable sequence that contains data representations of invocations of the underlying .NET event.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"target\"/> or <paramref name=\"eventName\"/> or <paramref name=\"scheduler\"/> is null.</exception>\n        /// <exception cref=\"InvalidOperationException\">The event could not be found. -or- The event does not conform to the standard .NET event pattern.</exception>\n        /// <remarks>","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Events.cs#L536-L572","documentation":"Observable.FromEventPattern(object target, string eventName) throws ArgumentNullException when eventName is null. The event name string is the key used for reflection lookup on the target's type, so Rx validates it as a required argument before attempting any reflection.","triggerScenarios":"Calling Observable.FromEventPattern(target, null) — target is a valid object but the event name string is null (eventName guard at line 554).","commonSituations":"Event name stored in a config/constant that was never set; using nameof() on a null-typed member or building the name dynamically and getting null; a rename removed the constant's value.","solutions":["Pass the event name as a literal or use nameof(target.Click), which also gives compile-time safety.","Initialize the configuration/constant supplying the event name.","Validate the name string before the call if it is dynamic.","Prefer the strongly-typed FromEventPattern overloads (e.g. with Action<EventHandler>) that avoid reflection by name entirely."],"exampleFix":"// before\nstring name = config[\"EventName\"]; // null\nvar xs = Observable.FromEventPattern(target, name);\n// after\nvar xs = Observable.FromEventPattern(target, nameof(target.Click));","handlingStrategy":"validation","validationCode":"if (string.IsNullOrEmpty(eventName)) throw new ArgumentException(\"Event name required\", nameof(eventName));","typeGuard":"bool HasEventName(string eventName) => !string.IsNullOrEmpty(eventName);","tryCatchPattern":"try { var xs = Observable.FromEventPattern(target, eventName); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"eventName\") { /* fall back to literal name */ }","preventionTips":["Always use nameof(...) for event names to get compile-time safety.","Never source event names from nullable config without a fallback.","Centralize event-name constants in one validated location.","Prefer delegate-based FromEventPattern overloads to skip reflection by name."],"tags":["null-argument","rx","reflection","event-pattern"],"backgroundTag":"null-argument","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"}