{"record":{"id":"42817760047ba4a1","repo":"dotnet/reactive","slug":"observer-distinct","errorCode":null,"errorMessage":"observer","messagePattern":"observer","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs","lineNumber":38,"sourceCode":"        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            return Create(\n                source,\n                comparer,\n                static (source, comparer, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer, comparer)));\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static IAsyncObserver<TSource> Distinct<TSource>(IAsyncObserver<TSource> observer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            return Distinct(observer, EqualityComparer<TSource>.Default);\n        }\n\n        public static IAsyncObserver<TSource> Distinct<TSource>(IAsyncObserver<TSource> observer, IEqualityComparer<TSource> comparer)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (comparer == null)\n                throw new ArgumentNullException(nameof(comparer));\n\n            var set = new HashSet<TSource>(comparer);\n\n            return Create<TSource>(\n                async x =>\n                {\n                    var added = false;\n","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs#L20-L56","documentation":"AsyncObserver.Distinct throws ArgumentNullException when the downstream IAsyncObserver<TSource> is null. This observer-facing factory is used inside custom operator implementations and delegates to Distinct(observer, EqualityComparer<TSource>.Default). The null check happens before any observer chain is built.","triggerScenarios":"Calling AsyncObserver.Distinct(null) from a custom subscribe path or forwarding a null observer argument.","commonSituations":"Hand-written operators where the observer passed into Create's subscribe delegate is misused or lost; wiring observers across layers where one layer passes null.","solutions":["Pass the real downstream observer you received in your subscribe delegate.","Add your own ArgumentNullException guards at the entry of your custom operator.","Prefer the built-in Create(source, observer) operator helper over manual observer construction."],"exampleFix":"// before\nAsyncObserver.Distinct(null); // throws\n// after\nreturn source.SubscribeSafeAsync(AsyncObserver.Distinct(downstreamObserver));","handlingStrategy":"validation","validationCode":"if (observer is null) throw new ArgumentNullException(nameof(observer));\nvar distinctObserver = AsyncObserver.Distinct(observer);","typeGuard":"bool HasDownstream<T>(IAsyncObserver<T>? o) => o is not null;","tryCatchPattern":"try\n{\n    var o = AsyncObserver.Distinct(observer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\")\n{\n    logger.LogError(ex, \"Distinct observer factory got null observer\");\n    throw;\n}","preventionTips":["Never construct observer chains with variables that may be null.","Guard custom operator entry points before delegating to observer factories.","Test custom operators' null-argument behavior explicitly."],"tags":["argument-null","async-rx","observer","custom-operators"],"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"}