{"record":{"id":"32516fc52a166bf0","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-source","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'source')","messagePattern":"Value cannot be null\\. \\(Parameter 'source'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/AsyncObservableExtensions.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.Reactive;\nusing System.Threading.Tasks;\n\nnamespace System\n{\n    public static class AsyncObservableExtensions\n    {\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (onNextAsync == null)\n                throw new ArgumentNullException(nameof(onNextAsync));\n\n            return source.SubscribeAsync(new AsyncObserver<T>(onNextAsync, ex => new ValueTask(Task.FromException(ex)), () => default));\n        }\n\n        public static ValueTask<IAsyncDisposable> SubscribeAsync<T>(this IAsyncObservable<T> source, Func<T, ValueTask> onNextAsync, Func<Exception, ValueTask> onErrorAsync)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (onNextAsync == null)\n                throw new ArgumentNullException(nameof(onNextAsync));\n            if (onErrorAsync == null)\n                throw new ArgumentNullException(nameof(onErrorAsync));\n\n            return source.SubscribeAsync(new AsyncObserver<T>(onNextAsync, onErrorAsync, () => default));\n        }\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/AsyncObservableExtensions.cs#L1-L33","documentation":"In the comparer-overload of ToLookup, the valueSelector is checked after observer and keySelector. Passing a null valueSelector prevents projecting element values into the Lookup<TKey,TValue> accumulator built via Aggregate, so ArgumentNullException(nameof(valueSelector)) is thrown at composition time (ToLookup.cs:138).","triggerScenarios":"Calling AsyncObservable.ToLookup(observer, keySelector, null, comparer) — 4-argument overload.","commonSituations":"Value selector supplied conditionally (only for some overloads); a projected delegate stored in a field that was never assigned; copy-paste between overloads dropping one argument.","solutions":["Pass a non-null Func<TSource,ValueTask<TValue>> as the value selector","Guard computed delegates with a null check before composing","Use x => x to keep whole elements as values instead of null"],"exampleFix":"// before\nvar op = AsyncObservable.ToLookup(sink, x => x.CustomerId, null, comparer);\n// after\nvar op = AsyncObservable.ToLookup(sink, x => x.CustomerId, x => x.Name, comparer);","handlingStrategy":"validation","validationCode":"if (keySelector is null) throw new ArgumentNullException(nameof(keySelector));\nif (valueSelector is null) throw new ArgumentNullException(nameof(valueSelector));","typeGuard":"static bool ValidSelectors<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, comparer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"valueSelector\")\n{\n    // fall back to identity selector or report configuration error\n}","preventionTips":["Treat all Func arguments to Rx operators as required, never optional","When conditionally choosing selectors, always assign a default in the else branch","Enable nullable reference types to catch potentially-null delegate variables at compile time"],"tags":["argument-null","value-selector","linq-operator"],"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"}