{"record":{"id":"b1b549d608b6d514","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-handler-observable-multiple","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'handler')","messagePattern":"Value cannot be null\\. \\(Parameter 'handler'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs","lineNumber":181,"sourceCode":"        /// <summary>\n        /// Continues an observable sequence that is terminated by an exception of the specified type with the observable sequence produced by the handler.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence and sequences returned by the exception handler function.</typeparam>\n        /// <typeparam name=\"TException\">The type of the exception to catch and handle. Needs to derive from <see cref=\"Exception\"/>.</typeparam>\n        /// <param name=\"source\">Source sequence.</param>\n        /// <param name=\"handler\">Exception handler function, producing another observable sequence.</param>\n        /// <returns>An observable sequence containing the source sequence's elements, followed by the elements produced by the handler's resulting observable sequence in case an exception occurred.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"handler\"/> is null.</exception>\n        public static IObservable<TSource> Catch<TSource, TException>(this IObservable<TSource> source, Func<TException, IObservable<TSource>> handler) where TException : Exception\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (handler == null)\n            {\n                throw new ArgumentNullException(nameof(handler));\n            }\n\n            return s_impl.Catch(source, handler);\n        }\n\n        /// <summary>\n        /// Continues an observable sequence that is terminated by an exception with the next observable sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence and handler sequence.</typeparam>\n        /// <param name=\"first\">First observable sequence whose exception (if any) is caught.</param>\n        /// <param name=\"second\">Second observable sequence used to produce results when an error occurred in the first sequence.</param>\n        /// <returns>An observable sequence containing the first sequence's elements, followed by the elements of the second sequence in case an exception occurred.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"first\"/> or <paramref name=\"second\"/> is null.</exception>\n        public static IObservable<TSource> Catch<TSource>(this IObservable<TSource> first, IObservable<TSource> second)\n        {\n            if (first == null)\n            {\n                throw new ArgumentNullException(nameof(first));","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Multiple.cs#L163-L199","documentation":"The Catch<TSource, TException>(source, handler) overload throws ArgumentNullException when the handler Func<TException, IObservable<TSource>> is null. The handler supplies the fallback sequence for a matching exception, so it is required and validated synchronously at the call site.","triggerScenarios":"Calling source.Catch(handler) where handler is null — a fallback delegate field not yet assigned, a null strategy from config, or passing a variable holding a method group that was conditionally resolved to null.","commonSituations":"Policy/fallback configuration where no fallback was defined and null was passed instead of skipping Catch; dependency injection of a 'fallback provider' returning null; refactoring removed the lambda but the call remained.","solutions":["Supply a concrete fallback handler, e.g. ex => Observable.Return(defaultValue).","If no fallback exists, do not call Catch — or pass a handler that rethrows/returns Observable.Throw.","Fix the config/dependency that was expected to provide the handler."],"exampleFix":"// before\nFunc<TimeoutException, IObservable<int>> fallback = maybeFallback;\nvar resilient = source.Catch(fallback); // throws if maybeFallback is null\n// after\nvar fallback = maybeFallback ?? (TimeoutException e) => Observable.Throw<int>(e);\nvar resilient = source.Catch(fallback);","handlingStrategy":"validation","validationCode":"ArgumentNullException.ThrowIfNull(handler);\nvar handler = maybeHandler ?? ((TimeoutException e) => Observable.Throw<TSource>(e));","typeGuard":"bool HasHandler<TSource, TException>(Func<TException, IObservable<TSource>>? h) where TException : Exception => h is not null;","tryCatchPattern":"try { var q = source.Catch(handler); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"handler\") { /* supply a fallback handler or skip Catch */ }","preventionTips":["Only wrap with Catch when a fallback policy actually exists; otherwise omit the operator.","Centralize fallback policies so handler delegates are always materialized (never null).","Fail fast on missing policy configuration at application startup."],"tags":["argument-null","rx","catch","argument-validation"],"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"}