{"record":{"id":"fc1e7d5f1c73e305","repo":"dotnet/reactive","slug":"observer","errorCode":null,"errorMessage":"observer","messagePattern":"observer","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Delay.cs","lineNumber":61,"sourceCode":"                source,\n                (dueTime, scheduler),\n                static async (source, state, observer) =>\n                {\n                    var (sink, drain) = await AsyncObserver.Delay(observer, state.dueTime, state.scheduler).ConfigureAwait(false);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, drain);\n                });\n        }\n    }\n\n    public partial class AsyncObserver\n    {\n        public static Task<(IAsyncObserver<TSource>, IAsyncDisposable)> Delay<TSource>(this IAsyncObserver<TSource> observer, TimeSpan dueTime)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n\n            return Delay(observer, dueTime, TaskPoolAsyncScheduler.Default);\n        }\n\n        public static async Task<(IAsyncObserver<TSource>, IAsyncDisposable)> Delay<TSource>(this IAsyncObserver<TSource> observer, TimeSpan dueTime, IAsyncScheduler scheduler)\n        {\n            if (observer == null)\n                throw new ArgumentNullException(nameof(observer));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            // TODO: Use stopwatch functionality.\n\n            var start = scheduler.Now;\n\n            var semaphore = new SemaphoreSlim(0);\n\n            var gate = new AsyncGate();","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Delay.cs#L43-L79","documentation":"The observer-side Delay extension throws ArgumentNullException because the downstream IAsyncObserver<TSource> is null. Observer operators compose onto an existing observer, and a null observer has nothing to forward delayed notifications to, so the argument is validated immediately. Note this overload already defaults the scheduler, so only the observer itself is at fault here.","triggerScenarios":"Calling AsyncObserver.Delay<TSource>(null, dueTime) — e.g. inside a custom SubscribeAsync where the 'observer' parameter or a captured observer variable is null.","commonSituations":"Writing a custom operator whose Create callback receives an observer that was never assigned; tests passing null observers; refactors that removed observer construction upstream.","solutions":["Pass a real IAsyncObserver<TSource> — typically the observer handed to your SubscribeAsync lambda.","If you wrap observers in a chain, verify the innermost observer is constructed before the Delay call.","Check that any factory producing the observer is not returning null."],"exampleFix":"// before\nawait AsyncObserver.Delay(observer, TimeSpan.FromSeconds(1)); // observer null here\n// after\nif (observer == null) throw new InvalidOperationException(\"observer not yet created\");\nawait AsyncObserver.Delay(observer, TimeSpan.FromSeconds(1));","handlingStrategy":"validation","validationCode":"if (observer is null) throw new InvalidOperationException(\"downstream observer not created before Delay\");\nvar (delayed, disp) = await AsyncObserver.Delay(observer, dueTime);","typeGuard":"static bool CanDelay<TSource>(IAsyncObserver<TSource>? o) => o is not null;","tryCatchPattern":"try { var r = await AsyncObserver.Delay(observer, due); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observer\") { /* log and rethrow with pipeline context */ throw; }","preventionTips":["In custom operators, apply observer extensions only after the observer parameter is known non-null.","Never let observer-factory helpers return null.","Use nullable annotations to catch null observers at compile time."],"tags":["argumentnull","observer","delay-operator","asyncrx"],"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"}