{"record":{"id":"f59d5ae29d40aeb4","repo":"dotnet/reactive","slug":"argumentnullexception-asyncobserver","errorCode":null,"errorMessage":"ArgumentNullException","messagePattern":"ArgumentNullException","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/AsyncObserver.cs","lineNumber":14,"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.Linq\n{\n    public static partial class AsyncObserver\n    {\n        public static IAsyncObserver<T> Create<T>(Func<T, ValueTask> onNextAsync)\n        {\n            if (onNextAsync == null)\n                throw new ArgumentNullException(nameof(onNextAsync));\n\n            return new AsyncObserver<T>(\n                onNextAsync,\n                ex => new ValueTask(Task.FromException(ex)),\n                () => default\n            );\n        }\n\n        public static IAsyncObserver<T> Create<T>(Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync, Func<ValueTask> onCompletedAsync)\n        {\n            if (onNextAsync == null)\n                throw new ArgumentNullException(nameof(onNextAsync));\n            if (onErrorAsync == null)\n                throw new ArgumentNullException(nameof(onErrorAsync));\n            if (onCompletedAsync == null)\n                throw new ArgumentNullException(nameof(onCompletedAsync));\n\n            return new AsyncObserver<T>(onNextAsync, onErrorAsync, onCompletedAsync);","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/AsyncObserver.cs#L1-L32","documentation":"AsyncObserver.Create<T>(onNextAsync) requires a non-null onNext delegate and throws ArgumentNullException when it is null. The other two handlers (onError, onCompleted) are defaulted internally, so onNext is the only mandatory argument. The check is synchronous and runs before the observer instance is created.","triggerScenarios":"Calling AsyncObserver.Create<T>(null) — typically Do(observerFactory) passing a null onNext lambda, e.g. x => SomeAsync() where a variable capture resolved to a null delegate.","commonSituations":"Passing a nullable Func field that was never assigned; using a conditional expression that yields null; calling Create from a generic helper where the delegate parameter defaulted to null.","solutions":["Supply a non-null onNextAsync delegate, e.g. AsyncObserver.Create<T>(async x => { await HandleAsync(x); }).","Check the variable holding the delegate for an unassigned/null value.","If all handlers are dynamic, switch to the full overload Create(onNext, onError, onCompleted) and validate each before calling."],"exampleFix":"// before\nAsyncObserver.Create<int>(onNext);\n// after\nif (onNext == null) onNext = x => new ValueTask(Task.CompletedTask);\nAsyncObserver.Create<int>(onNext);","handlingStrategy":"validation","validationCode":"if (onNextAsync is null) throw new ArgumentNullException(nameof(onNextAsync));\nvar observer = AsyncObserver.Create(onNextAsync);","typeGuard":"bool IsValidHandler<T>(Func<T, ValueTask> f) => f is not null;","tryCatchPattern":"try\n{\n    var observer = AsyncObserver.Create(onNextAsync);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"onNextAsync\")\n{\n    // substitute a default onNext or log the configuration bug\n}","preventionTips":["Initialize onNext lambdas inline rather than via nullable fields.","Never pass delegates from conditional expressions that can yield null.","Prefer the full Create(onNext, onError, onCompleted) overload when handlers are dynamic.","Write tests that exercise observer construction with all configured handlers."],"tags":["csharp","null-check","observer","argument-validation"],"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"}