{"record":{"id":"b50b6169c3c84531","repo":"dotnet/reactive","slug":"throw-new-argumentnullexception-nameof-source-retry","errorCode":null,"errorMessage":"throw new ArgumentNullException(nameof(source));","messagePattern":"throw new ArgumentNullException\\(nameof\\(source\\)\\);","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Retry.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.Linq;\nusing System.Reactive.Disposables;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> Retry<TSource>(this IAsyncObservable<TSource> source)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n\n            return Create(\n                source,\n                async static (source, observer) =>\n                {\n                    var (sink, inner) = AsyncObserver.Retry(observer, source);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, inner);\n                });\n        }\n\n        public static IAsyncObservable<TSource> Retry<TSource>(this IAsyncObservable<TSource> source, int retryCount)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (retryCount < 0)","sourceCodeStart":1,"sourceCodeEnd":33,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Retry.cs#L1-L33","documentation":"The parameterless Retry(source) operator validates its input and throws ArgumentNullException when source is null. Retry works by re-subscribing to the given observable on failure, so a null source leaves nothing to subscribe to and the guard fires before the operator is created.","triggerScenarios":"Calling AsyncObservable.Retry(null) with a source that came from a null-returning factory, an unset field, or a failed lookup.","commonSituations":"Chained pipeline construction where an earlier operator returned null on error; service-locator lookups returning null; optional streams that were never assigned.","solutions":["Guarantee the source observable is initialized before calling Retry.","Make source factories throw or return non-null fallback observables (e.g. AsyncObservable.Empty<T>()).","Coalesce: source ?? throw new InvalidOperationException(...) or a default empty source."],"exampleFix":"// before\nvar retried = AsyncObservable.Retry(GetSource()); // may return null\n// after\nvar src = GetSource() ?? AsyncObservable.Empty<int>();\nvar retried = AsyncObservable.Retry(src);","handlingStrategy":"validation","validationCode":"if (source is null) throw new InvalidOperationException(\"Retry requires a non-null source observable\");","typeGuard":"static bool IsValidSource<TSource>(IAsyncObservable<TSource> source) => source is not null;","tryCatchPattern":"try { var retried = AsyncObservable.Retry(source); } catch (ArgumentNullException ex) when (ex.ParamName == \"source\") { /* fix source provisioning */ }","preventionTips":["Return Empty<T>() instead of null from stream factories.","Verify service-locator/DI lookups succeed before retrying.","Assert pipeline inputs are assigned before operators are applied."],"tags":["null-argument","argument-validation","retry","reactive-extensions"],"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"}