{"record":{"id":"7e3a51ec6f507308","repo":"dotnet/reactive","slug":"source-distinct","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs","lineNumber":14,"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;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n\n            return Create(source, static (source, observer) => source.SubscribeSafeAsync(AsyncObserver.Distinct(observer)));\n        }\n\n        public static IAsyncObservable<TSource> Distinct<TSource>(IAsyncObservable<TSource> source, IEqualityComparer<TSource> comparer)\n        {\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","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Distinct.cs#L1-L32","documentation":"Distinct throws ArgumentNullException when the source IAsyncObservable<TSource> is null. The operator filters duplicate elements using a HashSet-backed observer and validates its source eagerly at composition time. Null source is a caller bug, not a recoverable condition.","triggerScenarios":"Calling AsyncObservable.Distinct(null) or invoking the extension method on a null reference (static form shown here takes source explicitly).","commonSituations":"Static invocation Distinct(source) where source comes from a nullable lookup; merging pipelines where one branch produced null.","solutions":["Ensure a non-null observable is passed to Distinct.","Fix the upstream producer that returned null instead of an observable.","Coalesce to AsyncObservable.Empty<TSource>() when null is an expected 'no data' case."],"exampleFix":"// before\nvar distinct = AsyncObservable.Distinct(source); // source == null\n// after\nvar distinct = source != null ? AsyncObservable.Distinct(source) : AsyncObservable.Empty<int>();","handlingStrategy":"validation","validationCode":"if (source is null) throw new InvalidOperationException(\"Distinct requires a non-null source\");\nvar distinct = AsyncObservable.Distinct(source);","typeGuard":"bool IsValidSource<T>(IAsyncObservable<T>? s) => s is not null;","tryCatchPattern":"try\n{\n    var distinct = AsyncObservable.Distinct(source);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\")\n{\n    logger.LogError(ex, \"Distinct called with null source\");\n    throw;\n}","preventionTips":["Treat null observables as bugs; return Empty<TSource>() from producers.","Use NRT and non-nullable return types on pipeline factories.","Avoid storing observables in nullable fields without initialization."],"tags":["argument-null","async-rx","operators","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"}