{"record":{"id":"99a638ac2b776c7d","repo":"dotnet/reactive","slug":"throw-new-argumentnullexception-nameof-sampler","errorCode":null,"errorMessage":"throw new ArgumentNullException(nameof(sampler));","messagePattern":"throw new ArgumentNullException\\(nameof\\(sampler\\)\\);","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sample.cs","lineNumber":19,"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.Concurrency;\nusing System.Reactive.Disposables;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> Sample<TSource, TSample>(this IAsyncObservable<TSource> source, IAsyncObservable<TSample> sampler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (sampler == null)\n                throw new ArgumentNullException(nameof(sampler));\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                sampler,\n                static async (source, sampler, observer) =>\n                {\n                    var (sourceSink, samplerSink) = AsyncObserver.Sample<TSource, TSample>(observer);\n\n                    var sourceSubscription = await source.SubscribeSafeAsync(sourceSink).ConfigureAwait(false);\n                    var samplerSubscription = await sampler.SubscribeSafeAsync(samplerSink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(sourceSubscription, samplerSubscription);\n                });\n        }\n\n        public static IAsyncObservable<TSource> Sample<TSource>(this IAsyncObservable<TSource> source, TimeSpan interval)\n        {\n            if (source == null)","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Sample.cs#L1-L37","documentation":"The Sample<TSource,TSample>(source, sampler) overload throws ArgumentNullException when the sampler observable is null. The sampler is the stream whose emissions trigger publishing the latest source value, so the operator requires both streams up front and validates them synchronously.","triggerScenarios":"Calling source.Sample(sampler) with a null sampler — e.g. a timer/sampler stream that failed to initialize, a conditional that returns null instead of a default sampler, or passing the result of a lookup that missed.","commonSituations":"Sampler built from a configuration-driven interval where config was missing and the builder returned null; unit test forgot to set up the sampler; a NuGet/version change made a previously non-null sampler nullable.","solutions":["Create the sampler before calling Sample (e.g. AsyncObservable.Interval(period) or another hot stream)","Guard at the composition site: if sampler == null, substitute AsyncObservable.Interval(defaultPeriod) or Empty","Fix the factory/DI path that produced the null sampler","Wrap in a helper that validates both arguments and throws a domain-specific error"],"exampleFix":"// before\nvar sampled = prices.Sample(configuredSampler); // null when config missing\n// after\nvar sampler = configuredSampler ?? AsyncObservable.Interval(TimeSpan.FromSeconds(1));\nvar sampled = prices.Sample(sampler);","handlingStrategy":"validation","validationCode":"if (sampler is null) sampler = AsyncObservable.Interval(TimeSpan.FromSeconds(1));\nvar sampled = source.Sample(sampler);","typeGuard":"static bool HasSampler<TSample>(IAsyncObservable<TSample>? s) => s is not null;","tryCatchPattern":"try\n{\n    var sampled = source.Sample(sampler);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"sampler\")\n{\n    sampler = AsyncObservable.Interval(defaultPeriod);\n    sampled = source.Sample(sampler);\n}","preventionTips":["Default missing samplers to a timed interval stream instead of null","Construct sampler and source together in a factory that returns a named pair","Use nullable reference type annotations on fields holding the sampler","Cover sampler construction in unit tests with config-missing scenarios"],"tags":["csharp","null-argument","async-reactive","argument-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-15T23:17:13.987Z"}