{"record":{"id":"7a95418521878985","repo":"dotnet/reactive","slug":"argumentnullexception-while","errorCode":null,"errorMessage":"ArgumentNullException","messagePattern":"ArgumentNullException","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/While.cs","lineNumber":17,"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.Disposables;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        // REVIEW: Use a tail-recursive sink.\n\n        public static IAsyncObservable<TSource> While<TSource>(Func<bool> condition, IAsyncObservable<TSource> source)\n        {\n            if (condition == null)\n                throw new ArgumentNullException(nameof(condition));\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n\n            return Create<TSource>(async observer =>\n            {\n                var subscription = new SerialAsyncDisposable();\n\n                var o = default(IAsyncObserver<TSource>);\n\n                o = AsyncObserver.CreateUnsafe<TSource>(\n                        observer.OnNextAsync,\n                        observer.OnErrorAsync,\n                        MoveNext\n                    );\n\n                async ValueTask MoveNext()\n                {\n                    var b = default(bool);","sourceCodeStart":1,"sourceCodeEnd":35,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/While.cs#L1-L35","documentation":"System.Reactive.Async's While operator requires a synchronous condition delegate and a source observable. The library throws ArgumentNullException immediately when either is null, failing fast at call time rather than producing an erroring observable. This protects the returned operator from undefined behavior during subscription.","triggerScenarios":"Calling AsyncObservable.While with a null condition Func<bool>, or with a null IAsyncObservable<TSource> source (e.g. a factory method returned null).","commonSituations":"Passing the result of a method that returned null instead of an observable; typos where a lambda variable is still null; refactoring away a default source without updating the call site.","solutions":["Ensure the condition delegate is a non-null Func<bool> (e.g. () => i < 10).","Ensure the source argument is a valid, non-null IAsyncObservable<TSource> before passing it.","If the source may come from a nullable expression, coalesce it with an empty observable or throw a descriptive error at your own boundary.","Wrap the call in ArgumentNullException handling only at top-level boundaries where inputs are external."],"exampleFix":"// before\nvar res = AsyncObservable.While(cond, maybeSource);\n// after\nif (maybeSource == null) maybeSource = AsyncObservable.Empty<int>();\nvar res = AsyncObservable.While(() => cond(), maybeSource);","handlingStrategy":"validation","validationCode":"if (condition == null) throw new ArgumentNullException(nameof(condition));\nif (source == null) throw new ArgumentNullException(nameof(source));\nvar res = AsyncObservable.While(condition, source);","typeGuard":"static bool IsValidWhileArgs<TSource>(Func<bool> condition, IAsyncObservable<TSource> source)\n    => condition is not null && source is not null;","tryCatchPattern":"try { var res = AsyncObservable.While(condition, source); }\ncatch (ArgumentNullException ex) when (ex.ParamName is \"condition\" or \"source\")\n{\n    // log and fall back to Empty or rethrow with context\n}","preventionTips":["Never pass possibly-null delegates or observables to Rx operators","Coalesce with AsyncObservable.Empty<TSource>() at composition boundaries","Enable nullable reference types to catch nulls at compile time","Keep argument order in mind: condition first, source second"],"tags":["csharp","argument-validation","null-argument","async-rx"],"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"}