{"record":{"id":"a670e916e29fee4a","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-oncompletedasync-a670e9","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onCompletedAsync')","messagePattern":"Value cannot be null\\. \\(Parameter 'onCompletedAsync'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Internal/UnsafeAsyncObserver.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 UnsafeAsyncObserver<T> : IAsyncObserver<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 UnsafeAsyncObserver(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        public ValueTask OnCompletedAsync() => _onCompletedAsync();\n\n        public ValueTask OnErrorAsync(Exception error) => _onErrorAsync(error ?? throw new ArgumentNullException(nameof(error)));\n\n        public ValueTask OnNextAsync(T value) => _onNextAsync(value);\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Internal/UnsafeAsyncObserver.cs#L1-L29","documentation":"UnsafeAsyncObserver's constructor requires a non-null onCompletedAsync delegate and throws ArgumentNullException when it is null. The library intentionally has no default completion handler so that subscription authors always define completion behavior explicitly. The guard fires immediately in the constructor, before any events are delivered.","triggerScenarios":"Calling new UnsafeAsyncObserver<T>(onNextAsync, onErrorAsync, null) — passing a null Func<ValueTask> as the third constructor argument.","commonSituations":"Building an observer that only cares about values or errors and forgetting completion; generating observers via code that conditionally omits the completion callback; converting from Rx observers where OnCompleted is implemented but was not wired through.","solutions":["Pass a non-null completion delegate, e.g. () => ValueTask.CompletedTask","Supply all three delegates at every UnsafeAsyncObserver construction site","Create a factory/builder with sensible defaults to avoid hand-rolling the three arguments each time"],"exampleFix":"// before\nvar observer = new UnsafeAsyncObserver<int>(\n    x => ValueTask.CompletedTask,\n    ex => ValueTask.CompletedTask,\n    null);\n// after\nvar observer = new UnsafeAsyncObserver<int>(\n    x => ValueTask.CompletedTask,\n    ex => ValueTask.CompletedTask,\n    () => ValueTask.CompletedTask);","handlingStrategy":"validation","validationCode":"if (onCompletedAsync == null) throw new ArgumentException(\"onCompletedAsync delegate is required\");","typeGuard":"static bool IsValidObserver<T>(Func<T, ValueTask> n, Func<Exception, ValueTask> e, Func<ValueTask> c) => n != null && e != null && c != null;","tryCatchPattern":"try { var obs = new UnsafeAsyncObserver<int>(onNext, onError, onCompleted); } catch (ArgumentNullException ex) { /* ex.ParamName == \"onCompletedAsync\" */ }","preventionTips":["Define completion handling even when it is trivial: () => ValueTask.CompletedTask","Centralize observer construction in a helper that fills in defaults","Check constructor argument count/order when refactoring"],"tags":["argumentnull","asyncrx","observer","null-check"],"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"}