{"record":{"id":"e621e4dfb7fdc184","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-observer-sum","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'observer')","messagePattern":"Value cannot be null\\. \\(Parameter 'observer'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sum.cs","lineNumber":14,"sourceCode":"﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<int> SumInt32(IAsyncObserver<int> observer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            var sum = 0;\n\n            return Create<int>(\n                async x =>\n                {\n                    try\n                    {\n                        checked\n                        {\n                            sum += x;\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        await observer.OnErrorAsync(ex).ConfigureAwait(false);\n                    }\n                },","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sum.cs#L1-L32","documentation":"This ArgumentNullException is thrown by AsyncObserver.SumInt32(IAsyncObserver<int>) when the downstream observer is null. This is a lower-level factory in System.Reactive.Async that builds the aggregation observer; it's normally called by the Sum operator but can be invoked directly in custom operator or observer-composition code. The parameter 'observer' names the null argument.","triggerScenarios":"Calling AsyncObserver.SumInt32(null) directly, or implementing a custom Create/Subscribe path that forwards a null observer (e.g. a custom IAsyncObservable whose Subscribe receives and passes through a null observer).","commonSituations":"Hit by authors of custom async-reactive operators, adapters wrapping other observer frameworks, or test code constructing observers piecemeal where the downstream observer was never created or a mock returned null.","solutions":["Pass a valid IAsyncObserver<int>, e.g. one built via CreateObserver or obtained from your subscription pipeline.","In custom Subscribe implementations, validate the observer argument and throw ArgumentNullException early (matching this library's behavior).","If a factory returns the observer, check it for null before composing SumInt32 around it."],"exampleFix":"// before\nvar sumObserver = AsyncObserver.SumInt32(_downstream); // _downstream may be null\n\n// after\nif (_downstream == null)\n    throw new InvalidOperationException(\"Downstream observer not attached\");\nvar sumObserver = AsyncObserver.SumInt32(_downstream);","handlingStrategy":"try-catch","validationCode":"if (downstream is null)\n    throw new ArgumentNullException(nameof(downstream));","typeGuard":"static bool HasObserver<T>(IAsyncObserver<T>? o) => o is not null;","tryCatchPattern":"try { var obs = AsyncObserver.SumInt32(downstream); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\")\n{\n    throw new InvalidOperationException(\"Observer pipeline not attached before SumInt32\", ex);\n}","preventionTips":["Always terminate observer chains with a concrete sink before wrapping with aggregation observers.","Add the standard guard clause to custom Subscribe implementations.","Configure test mocks to return non-null observers by default."],"tags":["argument-null","observer","async-rx","custom-operator"],"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"}