{"record":{"id":"75d36e0bbc5b31d6","repo":"dotnet/reactive","slug":"argumentnullexception-nameof-keyselector-tolookup","errorCode":null,"errorMessage":"ArgumentNullException(nameof(keySelector))","messagePattern":"ArgumentNullException\\(nameof\\(keySelector\\)\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/ToLookup.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.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<ILookup<TKey, TValue>> ToLookup<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (valueSelector == null)\n                throw new ArgumentNullException(nameof(valueSelector));\n\n            return CreateAsyncObservable<ILookup<TKey, TValue>>.From(\n                source,\n                (keySelector, valueSelector),\n                static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.ToLookup(observer, state.keySelector, state.valueSelector)));\n        }\n\n        public static IAsyncObservable<ILookup<TKey, TValue>> ToLookup<TSource, TKey, TValue>(this IAsyncObservable<TSource> source, Func<TSource, TKey> keySelector, Func<TSource, TValue> valueSelector, IEqualityComparer<TKey> comparer)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (valueSelector == null)\n                throw new ArgumentNullException(nameof(valueSelector));\n            if (comparer == null)","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/ToLookup.cs#L1-L36","documentation":"ToLookup uses keySelector to group each element under a lookup key. A null keySelector makes grouping impossible, so ArgumentNullException(Parameter 'keySelector') is thrown synchronously at the call site before any subscription occurs.","triggerScenarios":"Calling ToLookup(source, null, valueSelector) — e.g. a conditionally assigned key-selector delegate that ended up null.","commonSituations":"Dynamic query builders where the key selector is chosen per configuration and a missing mapping yields null; reflection-created delegates that failed silently.","solutions":["Supply a concrete key-selector function such as x => x.Key.","Validate any dynamically chosen selector for null before composing the query.","Centralize selector construction in a factory that throws a descriptive error instead of returning null."],"exampleFix":"// before\nvar lookup = source.ToLookup(keySelector, x => x.Val); // keySelector null\n// after\nvar lookup = source.ToLookup(x => x.Key, x => x.Val);","handlingStrategy":"validation","validationCode":"if (keySelector == null) throw new ArgumentException(\"keySelector must be provided\", nameof(keySelector));","typeGuard":"bool IsValidKeySelector<T,TKey>(Func<T,TKey> f) => f is not null;","tryCatchPattern":"try { var lookup = await source.ToLookup(keySelector, valueSelector); } catch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\") { /* supply default selector */ }","preventionTips":["Define key selectors inline as lambdas rather than nullable delegates","Validate configuration-driven selector resolution for null","Keep selector selection logic in a factory that always returns a delegate"],"tags":["null-argument","asyncrx","keyselector"],"backgroundTag":"missing-required-argument","analyzedSha":"94b5d5ab912789f5abe9a72138a25bbd716fe59c","analyzedAt":"2026-09-15T02:26:24.759Z","contentChangedAt":"2026-09-15T02:26:24.759Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}