{"record":{"id":"b5c7f71d84a8e215","repo":"dotnet/reactive","slug":"argumentnullexception-action-b5c7f7","errorCode":null,"errorMessage":"ArgumentNullException: action","messagePattern":"ArgumentNullException: action","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Concurrency/WindowsRuntimeThreadPoolScheduler.cs","lineNumber":82,"sourceCode":"        public WorkItemPriority Priority { get; }\n\n        /// <summary>\n        /// Gets the options that configure how work is scheduled.\n        /// </summary>\n        public WorkItemOptions Options { get; }\n\n        /// <summary>\n        /// Schedules an action to be executed.\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                throw new ArgumentNullException(nameof(action));\n\n            var userWorkItem = new SystemReactive::System.Reactive.Concurrency.UserWorkItem<TState>(this, state, action);\n            \n            var res = ThreadPool.RunAsync(\n                iaa => userWorkItem.Run(),\n                Priority,\n                Options);\n\n            userWorkItem.CancelQueueDisposable = res.AsDisposable();\n\n            return userWorkItem;\n        }\n\n        /// <summary>\n        /// Schedules an action to be executed after dueTime, using a Windows.System.Threading.ThreadPoolTimer object.\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>","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.WindowsRuntime/System.Reactive.Concurrency/WindowsRuntimeThreadPoolScheduler.cs#L64-L100","documentation":"WindowsRuntimeThreadPoolScheduler.Schedule<TState> requires a non-null scheduling delegate; it throws ArgumentNullException named 'action' when the Func<IScheduler, TState, IDisposable> passed to schedule work on the WinRT thread pool is null. The library validates up front because a null delegate cannot be wrapped in the UserWorkItem that runs on ThreadPool.RunAsync.","triggerScenarios":"Calling scheduler.Schedule(state, null) or passing a null delegate variable/ternary result as the action argument.","commonSituations":"Delegates built conditionally (e.g. cond ? action1 : null), methods that forward an optional action parameter, or refactored code where the lambda was accidentally removed.","solutions":["Pass a valid Func<IScheduler, TState, IDisposable> delegate or lambda to Schedule.","Check any variable holding the delegate for null before calling Schedule.","If the action may be absent, return a no-op scheduler lambda (e.g. (_, _) => Disposable.Empty) instead of null."],"exampleFix":"// before\nscheduler.Schedule(state, GetAction()); // GetAction() may return null\n// after\nvar action = GetAction() ?? ((sch, st) => Disposable.Empty);\nscheduler.Schedule(state, action);","handlingStrategy":"validation","validationCode":"if (action is null) throw new ArgumentNullException(nameof(action)); // or fix at call site:\n// scheduler.Schedule(state, action ?? ((s, st) => Disposable.Empty));","typeGuard":"bool IsValidAction<TState>(Func<IScheduler, TState, IDisposable>? a) => a is not null;","tryCatchPattern":"try { scheduler.Schedule(state, action); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"action\") { /* supply valid delegate or skip */ }","preventionTips":["Never return null from delegate factory methods; return no-op lambdas.","Enable nullable reference types so null delegate flows are caught at compile time.","Assert delegates non-null in wrapper methods before scheduling."],"tags":["csharp","scheduler","null-argument","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-23T08:17:48.524Z"}