{"record":{"id":"7f28e4fc62a78e5f","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-onerrorasync-7f28e4","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'onErrorAsync')","messagePattern":"Value cannot be null\\. \\(Parameter 'onErrorAsync'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Internal/UnsafeAsyncObserver.cs","lineNumber":18,"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 validates all three delegate arguments and throws ArgumentNullException when onErrorAsync is null. The library requires an explicit error-handling delegate so every observer has a well-defined OnErrorAsync path; there is no default no-op handler for this unsafe/fast-path type. This is an eager, fail-fast guard thrown at construction time, not during event delivery.","triggerScenarios":"Calling new UnsafeAsyncObserver<T>(onNextAsync, null, onCompletedAsync) — i.e. passing a null Func<Exception, ValueTask> as the second constructor argument.","commonSituations":"Writing a custom subscription that handles OnNext and OnCompleted but forgets the error callback; refactoring code that previously swallowed exceptions; mapping from an observer abstraction with optional error handling onto this API that requires all three delegates.","solutions":["Pass a non-null error handler delegate, e.g. ex => ValueTask.CompletedTask or one that logs the exception","Check every UnsafeAsyncObserver construction site and supply all three delegates (onNextAsync, onErrorAsync, onCompletedAsync)","Wrap construction in a helper factory with default delegates so callers can omit error handling explicitly"],"exampleFix":"// before\nvar observer = new UnsafeAsyncObserver<int>(\n    x => ValueTask.CompletedTask,\n    null,\n    () => ValueTask.CompletedTask);\n// after\nvar observer = new UnsafeAsyncObserver<int>(\n    x => ValueTask.CompletedTask,\n    ex => Console.Error.WriteLine(ex),\n    () => ValueTask.CompletedTask);","handlingStrategy":"validation","validationCode":"if (onErrorAsync == null) throw new ArgumentException(\"onErrorAsync 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 == \"onErrorAsync\" */ }","preventionTips":["Always supply all three delegates when constructing UnsafeAsyncObserver","Use named lambdas or methods so intent per delegate is clear","Never pass optional/conditional delegates; use no-op lambdas like () => ValueTask.CompletedTask"],"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"}