{"record":{"id":"6ab334f3d48c933d","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-action-6ab334","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'action')","messagePattern":"Value cannot be null\\. \\(Parameter 'action'\\)","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.Windows.Forms/ControlScheduler.cs","lineNumber":54,"sourceCode":"\n        /// <summary>\n        /// Gets the control associated with the ControlScheduler.\n        /// </summary>\n        public Control Control => _control;\n\n        /// <summary>\n        /// Schedules an action to be executed on the message loop associated with the control.\n        /// </summary>\n        /// <typeparam name=\"TState\">The type of the state passed to the scheduled action.</typeparam>\n        /// <param name=\"state\">State passed to the action to be executed.</param>\n        /// <param name=\"action\">Action to be executed.</param>\n        /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"action\"/> is null.</exception>\n        public override IDisposable Schedule<TState>(TState state, Func<IScheduler, TState, IDisposable> action)\n        {\n            if (action == null)\n            {\n                throw new ArgumentNullException(nameof(action));\n            }\n\n            if (_control.IsDisposed)\n            {\n                return Disposable.Empty;\n            }\n\n            var d = new SingleAssignmentDisposable();\n\n            _control.BeginInvoke(new Action(() =>\n            {\n                if (!_control.IsDisposed && !d.IsDisposed)\n                {\n                    d.Disposable = action(this, state);\n                }\n            }));\n\n            return d;","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.Windows.Forms/ControlScheduler.cs#L36-L72","documentation":"ControlScheduler.Schedule throws ArgumentNullException when the action delegate scheduled for execution is null. The guard exists because the scheduler would otherwise fail later, inside the WinForms message loop, when trying to invoke the delegate. Fail-fast at the public API boundary makes the caller's bug obvious.","triggerScenarios":"Calling controlScheduler.Schedule(state, null) or any overload where the Func<IScheduler, TState, IDisposable> action argument is null. Also hit indirectly by internal wrappers (Schedule, SchedulePeriodic, ScheduleRelative_) that forward a null action.","commonSituations":"Passing the result of a method that returned null as the action, storing scheduler actions in a nullable field that was never initialized, or wiring up scheduled work via reflection/config where the delegate resolved to null.","solutions":["Pass a non-null Func<IScheduler, TState, IDisposable> to Schedule.","Check where the delegate comes from; initialize the field/property that holds it before scheduling.","If the action may legitimately be absent, skip scheduling or use a no-op delegate such as static (s, st) => Disposable.Empty."],"exampleFix":"// before\nscheduler.Schedule(state, (Action<IScheduler,int>)null);\n// after\nscheduler.Schedule(state, (sch, st) => { DoWork(st); return Disposable.Empty; });","handlingStrategy":"validation","validationCode":"if (action is null) throw new ArgumentNullException(nameof(action)); // or assert before scheduling\nscheduler.Schedule(state, action);","typeGuard":"bool IsValidAction<TState>(Func<IScheduler, TState, IDisposable> a) => a is not null;","tryCatchPattern":"try { scheduler.Schedule(state, action); } catch (ArgumentNullException ex) when (ex.ParamName == \"action\") { Log(\"Scheduled action was null\"); }","preventionTips":["Never build scheduler delegates conditionally to null; use a no-op delegate instead","Initialize action fields/properties before scheduling","Prefer static lambdas so the compiler guarantees a delegate instance"],"tags":["csharp","rx","argumentnull","scheduler"],"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"}