{"record":{"id":"95413575d7ae9500","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-handler-954135","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'handler')","messagePattern":"Value cannot be null\\. \\(Parameter 'handler'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/EventPatternSourceBase.cs","lineNumber":104,"sourceCode":"        /// <param name=\"invokeHandler\">Delegate used to invoke the event for each element of the sequence.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"invokeHandler\"/> is <c>null</c>.</exception>\n        protected EventPatternSourceBase(IObservable<EventPattern<TSender, TEventArgs>> source, Action<Action<TSender?, TEventArgs>, /*object,*/ EventPattern<TSender, TEventArgs>> invokeHandler)\n        {\n            _source = source ?? throw new ArgumentNullException(nameof(source));\n            _invokeHandler = invokeHandler ?? throw new ArgumentNullException(nameof(invokeHandler));\n        }\n\n        /// <summary>\n        /// Adds the specified event handler, causing a subscription to the underlying source.\n        /// </summary>\n        /// <param name=\"handler\">Event handler to add. The same delegate should be passed to the <see cref=\"Remove(Delegate)\"/> operation in order to remove the event handler.</param>\n        /// <param name=\"invoke\">Invocation delegate to raise the event in the derived class.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"handler\"/> or <paramref name=\"invoke\"/> is <c>null</c>.</exception>\n        protected void Add(Delegate handler, Action<TSender?, TEventArgs> invoke)\n        {\n            if (handler == null)\n            {\n                throw new ArgumentNullException(nameof(handler));\n            }\n\n            if (invoke == null)\n            {\n                throw new ArgumentNullException(nameof(invoke));\n            }\n\n            var observer = new Observer(this, handler, invoke);\n            //\n            // [OK] Use of unsafe Subscribe: non-pretentious wrapper of an observable in an event; exceptions can occur during +=.\n            //\n            observer.SetResource(_source.Subscribe(observer));\n        }\n\n        private void Add(Delegate handler, IDisposable disposable)\n        {\n            lock (_subscriptions)\n            {","sourceCodeStart":86,"sourceCodeEnd":122,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/EventPatternSourceBase.cs#L86-L122","documentation":"EventPatternSourceBase.Add subscribes the handler to the underlying event-pattern source; a null handler delegate cannot be stored or later matched by Remove, so it is rejected. Fix: pass the actual event-handler delegate (the same instance you later pass to Remove).","triggerScenarios":"Calling the protected Add(Delegate handler, Action<TSender?,TEventArgs> invoke) from a derived class with handler == null, e.g. wiring `SomeEvent += null` routed through Add.","commonSituations":"Derived event-pattern wrappers whose handler is read from a nullable field or a failed delegate lookup before Add is called.","solutions":["Pass a non-null delegate to Add; ensure custom add/remove accessors supply the actual handler.","Guard: if (handler != null) Add(handler, invoke);"],"exampleFix":"// before\nAdd(handler, invoke);\n// after\nif (handler != null) { Add(handler, invoke); }","handlingStrategy":"validation","validationCode":"if (handler == null) return; // or throw, before calling Add","typeGuard":"bool CanAdd(Delegate? h) => h is not null;","tryCatchPattern":"try { Add(handler, invoke); } catch (ArgumentNullException ex) when (ex.ParamName == \"handler\") { /* log and skip registration */ }","preventionTips":["Keep the handler in a non-null field once captured in the add accessor.","Null-check delegates passed in from external code before registering."],"tags":["argument-null","event-handling"],"backgroundTag":"null-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}