{"record":{"id":"b4099beab0614b28","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-handler-observer-extensions","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/Observer.Extensions.cs","lineNumber":26,"sourceCode":"namespace System.Reactive\n{\n    /// <summary>\n    /// Provides a set of static methods for creating observers.\n    /// </summary>\n    public static class Observer\n    {\n        /// <summary>\n        /// Creates an observer from a notification callback.\n        /// </summary>\n        /// <typeparam name=\"T\">The type of the elements received by the observer.</typeparam>\n        /// <param name=\"handler\">Action that handles a notification.</param>\n        /// <returns>The observer object that invokes the specified handler using a notification corresponding to each message it receives.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"handler\"/> is null.</exception>\n        public static IObserver<T> ToObserver<T>(this Action<Notification<T>> handler)\n        {\n            if (handler == null)\n            {\n                throw new ArgumentNullException(nameof(handler));\n            }\n\n            return new AnonymousObserver<T>(\n                x => handler(Notification.CreateOnNext(x)),\n                exception => handler(Notification.CreateOnError<T>(exception)),\n                () => handler(Notification.CreateOnCompleted<T>())\n            );\n        }\n\n        /// <summary>\n        /// Creates a notification callback from an observer.\n        /// </summary>\n        /// <typeparam name=\"T\">The type of the elements received by the observer.</typeparam>\n        /// <param name=\"observer\">Observer object.</param>\n        /// <returns>The action that forwards its input notification to the underlying observer.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"observer\"/> is null.</exception>\n        [Diagnostics.CodeAnalysis.SuppressMessage(\"Microsoft.Naming\", \"CA1704:IdentifiersShouldBeSpelledCorrectly\", MessageId = \"Notifier\", Justification = \"Backward compat.\")]\n        public static Action<Notification<T>> ToNotifier<T>(this IObserver<T> observer)","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Observer.Extensions.cs#L8-L44","documentation":"Observer.ToObserver<T> converts an Action<Notification<T>> into an IObserver<T>. It throws ArgumentNullException when the handler delegate is null, because there is no sensible observer to construct without it.","triggerScenarios":"Calling handler: null with Observable.ToObserver<T>(null) or extension usage source.ToObserver((Action<Notification<int>>)null!).","commonSituations":"Passing a method group that failed to bind, a conditional result of a lookup that returned null, or refactoring that left a null lambda.","solutions":["Pass a non-null Action<Notification<T>> handling OnNext/OnError/OnCompleted","Null-check the delegate before calling ToObserver","Use Notification.CreateOnNext etc. inside a concrete handler implementation"],"exampleFix":"// before\nvar obs = source.ToObserver(null);\n// after\nvar obs = source.ToObserver(n => { switch (n.Kind) { case NotificationKind.OnNext: Console.WriteLine(n.Value); break; } });","handlingStrategy":"type-guard","validationCode":"if (handler == null) throw new InvalidOperationException(\"handler must be provided before calling ToObserver\");","typeGuard":"static bool IsValidHandler<T>(Action<Notification<T>>? h) => h is not null;","tryCatchPattern":"try { var obs = handler.ToObserver(); } catch (ArgumentNullException ex) when (ex.ParamName == \"handler\") { obs = Observer.Create<T>(_ => { }, _ => { }, () => { }); }","preventionTips":["Null-check delegates before passing to Rx extension methods","Avoid passing results of dictionary/reflection lookups directly as handlers","Use non-nullable delegate types (Action<Notification<T>> = default!) sparingly and initialize early"],"tags":["null-argument","rx","observer"],"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"}