{"record":{"id":"cfc8b6a0f33ff35b","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-onnextasync-asyncobserver","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onNextAsync')","messagePattern":"Value cannot be null\\. \\(Parameter 'onNextAsync'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObserver.cs","lineNumber":17,"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\n{\n    public class AsyncObserver<T> : AsyncObserverBase<T>\n    {\n        private readonly Func<T, ValueTask> _onNextAsync;\n        private readonly Func<Exception, ValueTask> _onErrorAsync;\n        private readonly Func<ValueTask> _onCompletedAsync;\n\n        public AsyncObserver(Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync, Func<ValueTask> onCompletedAsync)\n        {\n            _onNextAsync = onNextAsync ?? throw new ArgumentNullException(nameof(onNextAsync));\n            _onErrorAsync = onErrorAsync ?? throw new ArgumentNullException(nameof(onErrorAsync));\n            _onCompletedAsync = onCompletedAsync ?? throw new ArgumentNullException(nameof(onCompletedAsync));\n        }\n\n        protected override ValueTask OnCompletedAsyncCore() => _onCompletedAsync();\n\n        protected override ValueTask OnErrorAsyncCore(Exception error) => _onErrorAsync(error ?? throw new ArgumentNullException(nameof(error)));\n\n        protected override ValueTask OnNextAsyncCore(T value) => _onNextAsync(value);\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/AsyncObserver.cs#L1-L29","documentation":"The AsyncObserver constructor requires concrete delegate implementations for onNextAsync, onErrorAsync, and onCompletedAsync; it null-checks each and throws ArgumentNullException naming the offending parameter. A null onNextAsync would make it impossible to forward incoming elements, so construction fails immediately (line 17).","triggerScenarios":"new AsyncObserver<T>(null, onErrorAsync, onCompletedAsync) — constructing the observer directly with a null next-handler delegate.","commonSituations":"Building custom observers by hand instead of using the AsyncObserver.Create factory or SubscribeAsync extension helpers; generic factory code that passes through a caller-supplied (possibly null) delegate; refactors that changed a lambda to null intending to remove behavior.","solutions":["Supply a real next handler: ValueTask-returning lambda such as async x => await HandleAsync(x).","Use AsyncObserver.Create(onNextAsync, onErrorAsync, onCompletedAsync) or the SubscribeAsync extensions, which document the same null requirements.","Use the built-in no-op/empty observers (e.g. AsyncObserver.Empty<T>() style helpers) if you need an inert observer.","If onNext truly should do nothing, pass _ => default instead of null."],"exampleFix":"// before\nvar observer = new AsyncObserver<int>(null, ex => default, () => default);\n// after\nvar observer = new AsyncObserver<int>(x => { Console.WriteLine(x); return default; }, ex => default, () => default);","handlingStrategy":"validation","validationCode":"if (onNextAsync == null || onErrorAsync == null || onCompletedAsync == null)\n    throw new ArgumentException(\"AsyncObserver requires non-null onNextAsync, onErrorAsync, and onCompletedAsync delegates.\");\nvar observer = new AsyncObserver<T>(onNextAsync, onErrorAsync, onCompletedAsync);","typeGuard":null,"tryCatchPattern":"try\n{\n    var observer = new AsyncObserver<T>(onNextAsync, onErrorAsync, onCompletedAsync);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onNextAsync\")\n{\n    observer = new AsyncObserver<T>(_ => default, onErrorAsync, onCompletedAsync);\n}","preventionTips":["Prefer AsyncObserver.Create or SubscribeAsync extensions over constructing AsyncObserver directly.","Use no-op delegates (_ => default) instead of null when a handler is intentionally empty.","Validate delegate arguments in factory/wrapper code before passing them through."],"tags":["argument-null","constructor","rx","async"],"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"}