{"record":{"id":"5b9890d2be51282b","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-source-5b9890","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'source')","messagePattern":"Value cannot be null\\. \\(Parameter 'source'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Internal/EventPatternSourceBaseInternal.cs","lineNumber":36,"sourceCode":"    /// TODO: System.Reactive defines an EventPatternSourceBase. I (idg10) renamed this to EventPatternSourceBaseInternal to\n    /// avoid a conflict. Work out whether we could in fact just use the type defined in System.Reactive. It's not identical,\n    /// but perhaps it offers what we need.\n    /// </remarks>\n    internal abstract class EventPatternSourceBaseInternal<TSender, TEventArgs>\n    {\n        private readonly IAsyncObservable<EventPattern<TSender, TEventArgs>> _source;\n        private readonly Dictionary<Delegate, Stack<IAsyncDisposable>> _subscriptions;\n        private readonly Action<Action<TSender, TEventArgs>, /*object,*/ EventPattern<TSender, TEventArgs>> _invokeHandler;\n\n        /// <summary>\n        /// Creates a new event pattern source.\n        /// </summary>\n        /// <param name=\"source\">Source sequence to expose as an event.</param>\n        /// <param name=\"invokeHandler\">Delegate used to invoke the event for each element of the sequence.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"invokeHandler\"/> is null.</exception>\n        protected EventPatternSourceBaseInternal(IAsyncObservable<EventPattern<TSender, TEventArgs>> source, Action<Action<TSender, TEventArgs>, /*object,*/ EventPattern<TSender, TEventArgs>> invokeHandler)\n        {\n            _source = source ?? throw new ArgumentNullException(nameof(source));\n            _invokeHandler = invokeHandler ?? throw new ArgumentNullException(nameof(invokeHandler));\n            _subscriptions = new Dictionary<Delegate, Stack<IAsyncDisposable>>();\n        }\n\n        /// <summary>\n        /// Adds the specified event handler, causing a subscription to the underlying source.\n        /// </summary>\n        /// <param name=\"handler\">Event handler to add. The same delegate should be passed to the Remove operation in order to remove the event handler.</param>\n        /// <param name=\"invoke\">Invocation delegate to raise the event in the derived class.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"handler\"/> or <paramref name=\"invoke\"/> is null.</exception>\n        protected void Add(Delegate handler, Action<TSender, TEventArgs> invoke)\n        {\n            if (handler == null)\n                throw new ArgumentNullException(nameof(handler));\n            if (invoke == null)\n                throw new ArgumentNullException(nameof(invoke));\n\n            var gate = new object();","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Internal/EventPatternSourceBaseInternal.cs#L18-L54","documentation":"The protected EventPatternSourceBaseInternal constructor requires a non-null source sequence (IAsyncObservable<EventPattern<TSender,TEventArgs>>) since it exposes that sequence as an event. A null source is rejected immediately with ArgumentNullException, as documented by the constructor's <exception> tag.","triggerScenarios":"Calling the base constructor from a derived event-pattern class with a null source — e.g. FromEventPattern-style factory passing a null observable, or a chain like source.Where(...) that returned null.","commonSituations":"Implementing a custom event bridge class and passing an uninitialized observable field; an upstream factory method returning null; mis-ordered constructor arguments in a derived class.","solutions":["Pass a valid non-null IAsyncObservable as source.","Fix the factory/producer that returned the null source.","Guard in the derived factory before invoking the base constructor and throw a clearer error."],"exampleFix":"// before\npublic MyEventPatternSource(IAsyncObservable<EventPattern<object, EventArgs>> source)\n    : base(source, Invoke) { }\n// after\npublic MyEventPatternSource(IAsyncObservable<EventPattern<object, EventArgs>> source)\n    : base(source ?? throw new InvalidOperationException(\"source observable required\"), Invoke) { }","handlingStrategy":"validation","validationCode":"if (source is null) throw new ArgumentNullException(nameof(source));\n// then construct the derived EventPatternSourceBaseInternal with source","typeGuard":"static bool HasSource(IAsyncObservable<EventPattern<TSender,TEventArgs>>? s) => s is not null;","tryCatchPattern":"try { CreateEventPatternSource(source, invoke); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\")\n{ log.LogError(\"event-pattern source observable was null\"); }","preventionTips":["Ensure observable factories (FromEventPattern-style helpers) never return null; throw instead.","Order constructor arguments carefully in derived classes.","Enable nullable reference types to catch null observables at compile time."],"tags":["argument-null","event-pattern","observable"],"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"}