{"record":{"id":"8245738bb9308e2d","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-subscribeasync","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'subscribeAsync')","messagePattern":"Value cannot be null\\. \\(Parameter 'subscribeAsync'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObservable.cs","lineNumber":15,"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 AsyncObservable<T> : AsyncObservableBase<T>\n    {\n        private readonly Func<IAsyncObserver<T>, ValueTask<IAsyncDisposable>> _subscribeAsync;\n\n        public AsyncObservable(Func<IAsyncObserver<T>, ValueTask<IAsyncDisposable>> subscribeAsync)\n        {\n            _subscribeAsync = subscribeAsync ?? throw new ArgumentNullException(nameof(subscribeAsync));\n        }\n\n        protected override ValueTask<IAsyncDisposable> SubscribeAsyncCore(IAsyncObserver<T> observer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            return _subscribeAsync(observer);\n        }\n    }\n}\n","sourceCodeStart":1,"sourceCodeEnd":27,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/AsyncObservable.cs#L1-L27","documentation":"The ToLookup operator validates its delegate arguments eagerly when the operator is built. A null valueSelector means the operator cannot project elements to values once the lookup aggregation starts, so System.Reactive.Async throws ArgumentNullException(nameof(valueSelector)) immediately at subscription-wiring time rather than failing later inside the aggregation. This fail-fast contract mirrors LINQ's own argument guards.","triggerScenarios":"Calling AsyncObservable.ToLookup(observer, keySelector, null) — the 3-argument overload with sync Func selectors, at ToLookup.cs:126.","commonSituations":"Passing the result of a conditional expression or a helper that returned null for the value selector; refactoring where a Func variable became null; reflection or DI-created delegates resolving to null.","solutions":["Pass a non-null Func<TSource,TValue> as the third argument to ToLookup","If the selector is computed, check it for null before calling ToLookup","If a no-op projection is intended, use x => x or the appropriate identity/select overload instead of null"],"exampleFix":"// before\nvar op = AsyncObservable.ToLookup(source, x => x.Key, (Func<Order, string>)null);\n// after\nvar op = AsyncObservable.ToLookup(source, x => x.Key, x => x.Value);","handlingStrategy":"validation","validationCode":"if (source is null) throw new ArgumentNullException(nameof(source));\nif (keySelector is null) throw new ArgumentNullException(nameof(keySelector));\nif (valueSelector is null) throw new ArgumentNullException(nameof(valueSelector));","typeGuard":"static bool IsValidToLookupArgs<TSource,TKey,TValue>(Func<TSource,ValueTask<TKey>> k, Func<TSource,ValueTask<TValue>> v) => k != null && v != null;","tryCatchPattern":"try\n{\n    var op = AsyncObservable.ToLookup(observer, keySelector, valueSelector);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"valueSelector\")\n{\n    // supply a default selector or log configuration error\n}","preventionTips":["Never pass null for Func delegates; use identity lambdas like x => x instead","Validate optional delegate configuration at startup, not at pipeline composition","Keep overload calls complete — prefer named arguments for clarity"],"tags":["argument-null","linq-operator","fail-fast"],"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"}