{"record":{"id":"67e666177826b1ba","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-oncompletedasync-67e666","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onCompletedAsync')","messagePattern":"Value cannot be null\\. \\(Parameter 'onCompletedAsync'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObserver.cs","lineNumber":19,"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 null-checks all three delegates; onCompletedAsync was null, so it throws ArgumentNullException. Without a completion delegate the observer could not signal graceful end-of-stream, so construction fails at line 19.","triggerScenarios":"new AsyncObserver<T>(onNextAsync, onErrorAsync, null) — constructing with a null completion delegate.","commonSituations":"Assuming completion is optional for infinite streams and passing null; test scaffolding that fills in next/error but not completed; factory code plumbing through user-supplied delegates without defaults.","solutions":["Supply a completion handler, e.g. () => { Console.WriteLine(\"completed\"); return default; } or a no-op () => default.","Use AsyncObserver.Create or the SubscribeAsync extension overloads instead of constructing AsyncObserver directly.","Model truly-never-completing sequences with a no-op delegate rather than null.","Centralize observer creation in one helper that supplies default no-op delegates so nulls never reach the constructor."],"exampleFix":"// before\nvar observer = new AsyncObserver<int>(x => default, ex => default, null);\n// after\nvar observer = new AsyncObserver<int>(x => 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 == \"onCompletedAsync\")\n{\n    observer = new AsyncObserver<T>(onNextAsync, onErrorAsync, () => default);\n}","preventionTips":["Supply () => default for never-completing streams instead of null.","Use AsyncObserver.Create or SubscribeAsync helpers to avoid direct construction.","Build observers through a single factory that applies no-op defaults for missing handlers."],"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"}