{"record":{"id":"1a62d2da7c2c1d72","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-accumulator-observable","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'accumulator')","messagePattern":"Value cannot be null\\. \\(Parameter 'accumulator'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs","lineNumber":35,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TAccumulate\">The type of the result of the aggregation.</typeparam>\n        /// <param name=\"source\">An observable sequence to aggregate over.</param>\n        /// <param name=\"seed\">The initial accumulator value.</param>\n        /// <param name=\"accumulator\">An accumulator function to be invoked on each element.</param>\n        /// <returns>An observable sequence containing a single element with the final accumulator value.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"accumulator\"/> is null.</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<TAccumulate> Aggregate<TSource, TAccumulate>(this IObservable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> accumulator)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (accumulator == null)\n            {\n                throw new ArgumentNullException(nameof(accumulator));\n            }\n\n            return s_impl.Aggregate(source, seed, accumulator);\n        }\n\n        /// <summary>\n        /// Applies an accumulator function over an observable sequence, returning the result of the aggregation as a single element in the result sequence. The specified seed value is used as the initial accumulator value,\n        /// and the specified result selector function is used to select the result value.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TAccumulate\">The type of the accumulator value.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the resulting value.</typeparam>\n        /// <param name=\"source\">An observable sequence to aggregate over.</param>\n        /// <param name=\"seed\">The initial accumulator value.</param>\n        /// <param name=\"accumulator\">An accumulator function to be invoked on each element.</param>\n        /// <param name=\"resultSelector\">A function to transform the final accumulator value into the result value.</param>\n        /// <returns>An observable sequence containing a single element with the final accumulator value.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"accumulator\"/> or <paramref name=\"resultSelector\"/> is null.</exception>","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Aggregates.cs#L17-L53","documentation":"The seeded Aggregate overload throws ArgumentNullException when the accumulator delegate is null. Aggregate requires a Func<TAccumulate, TSource, TAccumulate> to combine the seed with each element; without it the operator is meaningless, so the call fails immediately at the public entry point.","triggerScenarios":"Calling Observable.Aggregate(source, seed, null) — typically when the lambda is built conditionally, supplied as a nullable field/property, or passed through from a caller whose argument was null.","commonSituations":"Storing reducer functions in configuration or a registry that returned null; overloads where the wrong optional parameter was bound; refactors that removed the lambda but left the call site compiling via a nullable delegate type.","solutions":["Pass a non-null accumulator lambda, e.g. (acc, x) => acc + x.","If the accumulator is resolved dynamically, fall back to a no-op reducer when the lookup returns null.","Enable nullable reference types so a possibly-null Func is caught at compile time.","Throw or log at the point the delegate is produced so the null never reaches Aggregate."],"exampleFix":"// before\nFunc<int, int, int> acc = reducers.TryGetValue(\"sum\", out var f) ? f : null;\nawait src.Aggregate(0, acc); // ArgumentNullException\n\n// after\nFunc<int, int, int> acc = reducers.TryGetValue(\"sum\", out var f) ? f : ((a, x) => a);\nawait src.Aggregate(0, acc);","handlingStrategy":"type-guard","validationCode":"if (accumulator is null) throw new ArgumentNullException(nameof(accumulator)); // fail before entering Rx","typeGuard":"static Func<TAcc, T, TAcc> NotNull<TAcc, T>(Func<TAcc, T, TAcc>? f) => f ?? throw new ArgumentNullException(nameof(f));","tryCatchPattern":"try { var result = source.Aggregate(seed, accumulator); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"accumulator\") { /* supply fallback reducer or surface config bug */ }","preventionTips":["Never store reducer delegates in nullable fields that can default to null; initialize with an identity/no-op function.","When resolving delegates from registries, always provide a fallback (?? defaultReducer).","Enable nullable reference types so nullable Func parameters are flagged by the compiler.","Keep lambdas inline at the call site unless dynamic selection is truly required."],"tags":["rx","argument-null","aggregate-operator","delegate-null"],"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"}