{"record":{"id":"43cef115fd7b1d2c","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-asynclock","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'asyncLock')","messagePattern":"Value cannot be null\\. \\(Parameter 'asyncLock'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Observer.Extensions.cs","lineNumber":281,"sourceCode":"        /// <summary>\n        /// Synchronizes access to the observer such that its callback methods cannot be called concurrently, using the specified asynchronous lock to protect against concurrent and reentrant access.\n        /// This overload is useful when coordinating multiple observers that access shared state by synchronizing on a common asynchronous lock.\n        /// </summary>\n        /// <typeparam name=\"T\">The type of the elements received by the source observer.</typeparam>\n        /// <param name=\"observer\">The observer whose callbacks should be synchronized.</param>\n        /// <param name=\"asyncLock\">Gate object to synchronize each observer call on.</param>\n        /// <returns>An observer that delivers callbacks to the specified observer in a synchronized manner.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"observer\"/> or <paramref name=\"asyncLock\"/> is null.</exception>\n        public static IObserver<T> Synchronize<T>(IObserver<T> observer, AsyncLock asyncLock)\n        {\n            if (observer == null)\n            {\n                throw new ArgumentNullException(nameof(observer));\n            }\n\n            if (asyncLock == null)\n            {\n                throw new ArgumentNullException(nameof(asyncLock));\n            }\n\n            return new AsyncLockObserver<T>(observer, asyncLock);\n        }\n\n        /// <summary>\n        /// Schedules the invocation of observer methods on the given scheduler.\n        /// </summary>\n        /// <typeparam name=\"T\">The type of the elements received by the source observer.</typeparam>\n        /// <param name=\"observer\">The observer to schedule messages for.</param>\n        /// <param name=\"scheduler\">Scheduler to schedule observer messages on.</param>\n        /// <returns>Observer whose messages are scheduled on the given scheduler.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"observer\"/> or <paramref name=\"scheduler\"/> is null.</exception>\n        public static IObserver<T> NotifyOn<T>(this IObserver<T> observer, IScheduler scheduler)\n        {\n            if (observer == null)\n            {\n                throw new ArgumentNullException(nameof(observer));","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Observer.Extensions.cs#L263-L299","documentation":"Observer.Synchronize<T>(IObserver<T>, AsyncLock) throws ArgumentNullException when the asyncLock parameter is null. The AsyncLock provides the mutual exclusion for notifications delivered to the observer; without it the wrapper cannot function, so Rx validates it upfront.","triggerScenarios":"Calling Observer.Synchronize(observer, null) — commonly when the AsyncLock is created lazily, disposed and nulled earlier, or accidentally passing null in place of a gate/lock object.","commonSituations":"AsyncLock disposed with the owning class and nulled, then reused; a factory method returning null; copy-paste between the object-gate and AsyncLock overloads.","solutions":["Create and pass an AsyncLock instance: new AsyncLock()","Ensure the AsyncLock field is initialized before use (readonly field initialized inline)","Do not null out the AsyncLock on dispose if it will be referenced again; keep a fresh instance per observer chain","Verify you are targeting the correct overload (object gate vs AsyncLock) and supply the matching type"],"exampleFix":"// before\nAsyncLock gate = _lock; // null after dispose\nvar synced = Observer.Synchronize(observer, gate);\n// after\nusing var asyncLock = new AsyncLock();\nvar synced = Observer.Synchronize(observer, asyncLock);","handlingStrategy":"validation","validationCode":"if (observer is null) throw new ArgumentNullException(nameof(observer));\nif (asyncLock is null) asyncLock = new AsyncLock();","typeGuard":"static bool HasAsyncLock(AsyncLock? l) => l is not null;","tryCatchPattern":"try { var synced = Observer.Synchronize(observer, asyncLock); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"asyncLock\")\n{\n    asyncLock = new AsyncLock();\n    var synced = Observer.Synchronize(observer, asyncLock);\n}","preventionTips":["Initialize AsyncLock fields inline: private readonly AsyncLock _lock = new AsyncLock();","Do not null the AsyncLock when disposing if it may be reused","Create a fresh AsyncLock per observer chain rather than sharing nullable instances","Track dispose lifecycle so a disposed lock is never passed again"],"tags":["null-argument","dotnet","rx","argument-validation"],"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"}