{"record":{"id":"317c5b3d00a242db","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-observer-average","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/Average.cs","lineNumber":12,"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\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<int> AverageInt32(IAsyncObserver<double> observer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            var sum = 0L;\n            var count = 0L;\n\n            return Create<int>(\n                async x =>\n                {\n                    try\n                    {\n                        checked\n                        {\n                            sum += x;\n                            count++;\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        await observer.OnErrorAsync(ex).ConfigureAwait(false);","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Average.cs#L1-L30","documentation":"AverageInt32 is the internal AsyncObserver factory that builds the per-item averaging observer for int sequences. It throws ArgumentNullException ('Value cannot be null.', Parameter 'observer') when the downstream IAsyncObserver<double> sink is null. End users normally never call this directly; it is reached through AsyncObserver.Average/Sum-style operators, so a null here means the operator composition passed a null observer internally or you invoked AsyncObserver.AverageInt32 manually with null.","triggerScenarios":"Directly calling AsyncObserver.AverageInt32(null) (e.g. building a custom subscription/observer pipeline); writing a custom operator that forwards a null observer into AverageInt32; a mis-implemented CreateAsyncObservable shim that hands a null downstream observer to the operator lambda.","commonSituations":"Custom operator authors wiring AsyncObserver composition helpers by hand and forgetting to pass the real downstream observer; passing a nullable observer field that was assigned after subscription; copy-pasted operator boilerplate where the observer variable was renamed to a null-valued parameter.","solutions":["If calling AsyncObserver.AverageInt32 directly, pass the actual downstream IAsyncObserver<double> you received, never null.","In custom operator code, ensure you forward the observer supplied by SubscribeSafeAsync/Create rather than a separately declared (possibly null) variable.","Add a null guard before the call and throw a more descriptive exception naming your own operator for easier diagnosis.","If you hit this via the public Average() operator only, report/check for a library bug — the public surface always passes a non-null observer."],"exampleFix":"// before\nIAsyncObserver<double> sink = null;\nvar avgObserver = AsyncObserver.AverageInt32(sink); // ArgumentNullException\n\n// after\nIAsyncObserver<double> sink = downstreamObserver ?? throw new ArgumentNullException(nameof(downstreamObserver));\nvar avgObserver = AsyncObserver.AverageInt32(sink);","handlingStrategy":"validation","validationCode":"if (downstream == null) throw new ArgumentNullException(nameof(downstream), \"AverageInt32 requires a non-null IAsyncObserver<double>\");\nvar avgObserver = AsyncObserver.AverageInt32(downstream);","typeGuard":"static bool IsValidObserver(IAsyncObserver<double>? observer) => observer is not null;","tryCatchPattern":"try { var obs = AsyncObserver.AverageInt32(downstream); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\") { logger.LogError(ex, \"null observer passed to AverageInt32 composition\"); throw; }","preventionTips":["Always forward the observer supplied by SubscribeSafeAsync/Create in custom operators","Initialize observer mocks in test setup, not lazily","Use non-nullable observer parameters in your custom operator signatures","Debug.Assert(observer != null) at composition sites"],"tags":["argument-null","asyncrx","observer","average-int32"],"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"}