{"record":{"id":"35d7c1380f8f5b04","repo":"dotnet/reactive","slug":"observablefactory","errorCode":null,"errorMessage":"observableFactory","messagePattern":"observableFactory","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Defer.cs","lineNumber":26,"sourceCode":"\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> Defer<TSource>(Func<IAsyncObservable<TSource>> observableFactory)\n        {\n            if (observableFactory == null)\n                throw new ArgumentNullException(nameof(observableFactory));\n\n            return Defer(() => new ValueTask<IAsyncObservable<TSource>>(observableFactory()));\n        }\n\n        public static IAsyncObservable<TSource> DeferAsync<TSource>(Func<ValueTask<IAsyncObservable<TSource>>> observableFactory) => Defer(observableFactory);\n\n        public static IAsyncObservable<TSource> Defer<TSource>(Func<ValueTask<IAsyncObservable<TSource>>> observableFactory)\n        {\n            if (observableFactory == null)\n                throw new ArgumentNullException(nameof(observableFactory));\n\n            return Create<TSource>(async observer =>\n            {\n                var source = default(IAsyncObservable<TSource>);\n\n                try\n                {\n                    source = await observableFactory().ConfigureAwait(false);\n                }\n                catch (Exception ex)\n                {\n                    await observer.OnErrorAsync(ex).ConfigureAwait(false);\n                    return AsyncDisposable.Nop;\n                }\n\n                return await source.SubscribeSafeAsync(observer).ConfigureAwait(false);\n            });\n        }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Defer.cs#L8-L44","documentation":"The ValueTask-based overload Defer<TSource>(Func<ValueTask<IAsyncObservable<TSource>>>) (also reached via DeferAsync) throws ArgumentNullException naming 'observableFactory' when the async factory delegate is null. The factory is invoked inside Create at subscription time, so a null must be rejected up front.","triggerScenarios":"Calling AsyncObservable.Defer<TSource>((Func<ValueTask<IAsyncObservable<TSource>>>)null) or DeferAsync<TSource>(null); also calling Defer with a sync Func that the compiler resolved to the ValueTask overload as null.","commonSituations":"Async factory supplied by a nullable delegate field or DI-resolved function that was never assigned; overload-resolution confusion between the sync, ValueTask, and CancellationToken ValueTask variants of Defer.","solutions":["Provide a non-null async factory: () => new ValueTask<IAsyncObservable<T>>(source).","Verify you called the intended overload; use DeferAsync for ValueTask-returning factories.","Null-check the factory delegate before passing it into Defer/DeferAsync."],"exampleFix":"// before\nFunc<ValueTask<IAsyncObservable<int>>> factory = maybeNull;\nvar xs = AsyncObservable.DeferAsync(factory);\n// after\nvar xs = AsyncObservable.DeferAsync(factory ?? throw new ArgumentNullException(nameof(factory)));","handlingStrategy":"validation","validationCode":"if (observableFactory is null) throw new ArgumentNullException(nameof(observableFactory));\nvar xs = AsyncObservable.DeferAsync(observableFactory);","typeGuard":"static bool IsValidAsyncFactory<T>(Func<ValueTask<IAsyncObservable<T>>> f) => f is not null;","tryCatchPattern":"try\n{\n    var xs = AsyncObservable.DeferAsync(factory);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"observableFactory\")\n{\n    // async ValueTask factory was null\n}","preventionTips":["Be explicit about which Defer/DeferAsync overload you intend; avoid relying on overload resolution with nulls.","Initialize async factory delegates eagerly or mark them 'required'.","Add Debug.Assert(factory != null) in composition code to catch issues in development."],"tags":["null-argument","rx","defer","async"],"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"}