{"record":{"id":"84b31c593b27bac3","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-selector-observable","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'selector')","messagePattern":"Value cannot be null\\. \\(Parameter 'selector'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs","lineNumber":385,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">A sequence of values to calculate the average of.</param>\n        /// <param name=\"selector\">A transform function to apply to each element.</param>\n        /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"selector\"/> is null.</exception>\n        /// <exception cref=\"InvalidOperationException\">(Asynchronous) The source sequence is empty.</exception>\n        /// <exception cref=\"OverflowException\">(Asynchronous) The sum of the projected values for the elements in the source sequence is larger than <see cref=\"decimal.MaxValue\"/>.</exception>\n        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>\n        public static IObservable<decimal> Average<TSource>(this IObservable<TSource> source, Func<TSource, decimal> selector)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (selector == null)\n            {\n                throw new ArgumentNullException(nameof(selector));\n            }\n\n            return s_impl.Average(source, selector);\n        }\n\n        /// <summary>\n        /// Computes the average of an observable sequence of <see cref=\"double\" /> values that are obtained by invoking a transform function on each element of the input sequence.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">A sequence of values to calculate the average of.</param>\n        /// <param name=\"selector\">A transform function to apply to each element.</param>\n        /// <returns>An observable sequence containing a single element with the average of the sequence of values.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"selector\"/> is null.</exception>\n        /// <exception cref=\"InvalidOperationException\">(Asynchronous) The source sequence is empty.</exception>\n        /// <remarks>The return type of this operator differs from the corresponding operator on IEnumerable in order to retain asynchronous behavior.</remarks>\n        public static IObservable<double> Average<TSource>(this IObservable<TSource> source, Func<TSource, double> selector)\n        {\n            if (source == null)","sourceCodeStart":367,"sourceCodeEnd":403,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs#L367-L403","documentation":"The decimal-selector Average overload throws ArgumentNullException(\"selector\") when the projection function passed is null. The source check has already passed; the selector delegate is validated second.","triggerScenarios":"Calling observable.Average((Func<T, decimal>)someField) where someField is a null delegate — e.g. an uninitialized selector field or a null entry read from configuration/DI.","commonSituations":"Dynamic selector selection (strategy pattern) where the default branch forgets to assign a projection; reflection-built pipelines passing null delegates.","solutions":["Supply a concrete selector lambda instead of the null delegate.","Guard: if (selector == null) selector = x => (decimal)x; or use a default projection.","Check where the delegate comes from (config, DI, dictionary) and fix the null assignment."],"exampleFix":"// before\nFunc<Order, decimal> sel = GetSelector(); // returns null\nvar avg = orders.Average(sel);\n// after\nvar avg = orders.Average(o => o.Total);","handlingStrategy":"validation","validationCode":"if (selector is null) selector = static o => o.Total; // or fail fast\nvar avg = orders.Average(selector);","typeGuard":"static bool HasSelector<T>(Func<T, decimal>? f) => f is not null;","tryCatchPattern":"try { var avg = orders.Average(selector); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"selector\") { /* install default selector */ }","preventionTips":["Never store selectors in nullable fields without defaults.","Validate delegate registrations (config/DI/registry) at load time.","Prefer inline lambdas over nullable delegate variables for fixed projections."],"tags":["null-reference","argument-validation","rx","delegate","projection"],"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"}