{"record":{"id":"694ecee6e6188010","repo":"dotnet/reactive","slug":"source-delaysubscription","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/DelaySubscription.cs","lineNumber":15,"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;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> DelaySubscription<TSource>(this IAsyncObservable<TSource> source, TimeSpan dueTime)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n\n            return DelaySubscription(source, dueTime, TaskPoolAsyncScheduler.Default);\n        }\n\n        public static IAsyncObservable<TSource> DelaySubscription<TSource>(this IAsyncObservable<TSource> source, TimeSpan dueTime, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return Create(\n                source,\n                (dueTime, scheduler),\n                static async (source, state, observer) =>\n                {\n                    var d = new CompositeAsyncDisposable();\n","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/DelaySubscription.cs#L1-L33","documentation":"The TimeSpan-based DelaySubscription operator throws ArgumentNullException because the source observable is null. DelaySubscription postpones the Subscribe call itself rather than the notifications; it still requires a real target observable to subscribe to later, so null is rejected at composition time.","triggerScenarios":"Calling DelaySubscription<TSource>(null, dueTime) — the overload without an explicit scheduler.","commonSituations":"Building pipelines from nullable observables obtained from caches or optionals; misordered initialization where DelaySubscription is applied before the source is created.","solutions":["Initialize the source observable before applying DelaySubscription.","Coalesce null sources to AsyncObservable.Empty<TSource>() when absence is legitimate.","Add a guard or debug assertion at the pipeline construction site to catch nulls early."],"exampleFix":"// before\nvar sub = maybeSource.DelaySubscription(TimeSpan.FromSeconds(5));\n// after\nvar sub = (maybeSource ?? AsyncObservable.Empty<int>()).DelaySubscription(TimeSpan.FromSeconds(5));","handlingStrategy":"validation","validationCode":"if (source is null) throw new InvalidOperationException(\"DelaySubscription requires a source; got null\");\nvar sub = source.DelaySubscription(TimeSpan.FromSeconds(5));","typeGuard":"static bool Delayable<TSource>(IAsyncObservable<TSource>? s) => s is not null;","tryCatchPattern":"try { var s = source.DelaySubscription(due); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\") { var s = AsyncObservable.Empty<int>().DelaySubscription(due); }","preventionTips":["Apply DelaySubscription only after source creation completes.","Never cache observables in nullable fields without initialization checks.","Return Empty/Throw observables instead of null from producers."],"tags":["argumentnull","null-check","delaysubscription","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"}