{"record":{"id":"85a87ce85d429c0f","repo":"dotnet/reactive","slug":"argumentnullexception-nameof-keyselector","errorCode":null,"errorMessage":"ArgumentNullException(nameof(keySelector))","messagePattern":"ArgumentNullException\\(nameof\\(keySelector\\)\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/DistinctUntilChanged.cs","lineNumber":125,"sourceCode":"            return DistinctUntilChanged(observer, x => x, comparer);\n        }\n\n        public static IAsyncObserver<TSource> DistinctUntilChanged<TSource, TKey>(IAsyncObserver<TSource> observer, Func<TSource, TKey> keySelector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n\n            return DistinctUntilChanged(observer, keySelector, EqualityComparer<TKey>.Default);\n        }\n\n        public static IAsyncObserver<TSource> DistinctUntilChanged<TSource, TKey>(IAsyncObserver<TSource> observer, Func<TSource, ValueTask<TKey>> keySelector)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n\n            return DistinctUntilChanged(observer, keySelector, EqualityComparer<TKey>.Default);\n        }\n\n        public static IAsyncObserver<TSource> DistinctUntilChanged<TSource, TKey>(IAsyncObserver<TSource> observer, Func<TSource, TKey> keySelector, IEqualityComparer<TKey> comparer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (keySelector == null)\n                throw new ArgumentNullException(nameof(keySelector));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            var hasCurrentKey = false;\n            var currentKey = default(TKey);\n\n            return Create<TSource>(\n                async x =>","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/DistinctUntilChanged.cs#L107-L143","documentation":"System.ArgumentNullException with ParamName 'keySelector' thrown by AsyncObserver.DistinctUntilChanged<TSource,TKey>(IAsyncObserver<TSource>, Func<TSource, ValueTask<TKey>>) when the async key selector is null. The selector must produce a ValueTask<TKey> per element for consecutive-difference comparison.","triggerScenarios":"Calling AsyncObserver.DistinctUntilChanged<TSource,TKey>(observer, (Func<TSource, ValueTask<TKey>>)null).","commonSituations":"Async delegate resolved from config/registry was null; overload mismatch left the parameter bound to a null lambda variable; refactor dropped the selector assignment.","solutions":["Provide a valid async selector: async x => (ValueTask<TKey>)ComputeKeyAsync(x).","Switch to the synchronous selector overload if no async work is needed.","Initialize the delegate before composing the observer."],"exampleFix":"// before\nFunc<Event, ValueTask<string>> key = null;\nvar o = AsyncObserver.DistinctUntilChanged<Event, string>(observer, key);\n// after\nvar o = AsyncObserver.DistinctUntilChanged<Event, string>(observer, async e => await ResolveKeyAsync(e));","handlingStrategy":"validation","validationCode":"if (asyncKeySelector is null) throw new ArgumentNullException(nameof(asyncKeySelector));\nvar obs = AsyncObserver.DistinctUntilChanged<T, TKey>(observer, asyncKeySelector);","typeGuard":"bool IsValidAsyncSelector<TSource, TKey>(Func<TSource, ValueTask<TKey>>? f) => f is not null;","tryCatchPattern":"try\n{\n    var obs = AsyncObserver.DistinctUntilChanged<T, TKey>(observer, asyncKeySelector);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"keySelector\")\n{\n    var obs = AsyncObserver.DistinctUntilChanged<T, TKey>(observer, x => x.DefaultKey);\n}","preventionTips":["Bind async selectors to concrete async methods, not nullable delegate fields","Prefer the synchronous selector overload when no I/O is required","Fail fast at startup if a configured selector fails to resolve"],"tags":["argumentnull","asyncrx","keyselector","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-23T08:17:48.524Z"}