{"record":{"id":"39d5fa08656bf526","repo":"dotnet/reactive","slug":"action-parameter-action-localscheduler","errorCode":null,"errorMessage":"action (Parameter 'action')","messagePattern":"action \\(Parameter 'action'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.cs","lineNumber":29,"sourceCode":"    {\n        /// <summary>\n        /// Gets the scheduler's notion of current time.\n        /// </summary>\n        public virtual DateTimeOffset Now => Scheduler.Now;\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 <c>null</c>.</exception>\n        public virtual 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            return Schedule(state, TimeSpan.Zero, action);\n        }\n\n        /// <summary>\n        /// Schedules an action to be executed after dueTime.\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        /// <param name=\"dueTime\">Relative time after which to execute the action.</param>\n        /// <returns>The disposable object used to cancel the scheduled action (best effort).</returns>\n        public abstract IDisposable Schedule<TState>(TState state, TimeSpan dueTime, Func<IScheduler, TState, IDisposable> action);\n\n        /// <summary>\n        /// Schedules an action to be executed at dueTime.\n        /// </summary>","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Concurrency/LocalScheduler.cs#L11-L47","documentation":"LocalScheduler.Schedule<TState>(state, action) — the base class for concurrency-restricted schedulers like NewThreadScheduler/DefaultScheduler — throws ArgumentNullException when action is null, before forwarding to the TimeSpan overload with TimeSpan.Zero.","triggerScenarios":"Calling any derived scheduler (e.g. Scheduler.Default, NewThreadScheduler.Default) with the immediate-overload and a null action, or Rx operators (Tick, ScheduleAction, recursion helpers) passing a null delegate through.","commonSituations":"Using Rx default scheduling (Observable.Timer, Delay, SubscribeOn) with user callbacks that are null; plugin/observer patterns where a callback hook was never registered.","solutions":["Pass a non-null lambda to Schedule; find the unassigned delegate upstream.","Guard at your abstraction layer: Require.NotNull(action, nameof(action)).","If work is optional, wrap: action ?? ((s, st) => Disposable.Empty)."],"exampleFix":"// before\nAction<int> cb = null;\nScheduler.Default.Schedule(0, (s, st) => { cb(st); return Disposable.Empty; }); // throws\n\n// after\ncb ??= _ => { };\nScheduler.Default.Schedule(0, (s, st) => { cb(st); return Disposable.Empty; });","handlingStrategy":"validation","validationCode":"if (action is null) throw new ArgumentNullException(nameof(action));\nScheduler.Default.Schedule(state, action);","typeGuard":"static bool ValidWork<TState>(Func<IScheduler, TState, IDisposable>? a) => a is not null;","tryCatchPattern":"try { Scheduler.Default.Schedule(state, action); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"action\")\n{\n    // user callback hook was never registered\n}","preventionTips":["Require observer/callback hooks at construction time","Provide no-op defaults for optional callbacks","Cover Rx operator usage in tests with real scheduler delegates"],"tags":["null-argument","scheduler","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"}