{"record":{"id":"d861a083619dc6c1","repo":"dotnet/reactive","slug":"action-parameter-action-historicalscheduler","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/HistoricalScheduler.cs","lineNumber":142,"sourceCode":"            }\n\n            return null;\n        }\n\n        /// <summary>\n        /// Schedules an action to be executed at <paramref name=\"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\">Absolute time at which to execute the action.</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 override IDisposable ScheduleAbsolute<TState>(TState state, DateTimeOffset dueTime, Func<IScheduler, TState, IDisposable> action)\n        {\n            if (action == null)\n            {\n                throw new ArgumentNullException(nameof(action));\n            }\n\n            ScheduledItem<DateTimeOffset, TState>? si = null;\n\n            var run = new Func<IScheduler, TState, IDisposable>((scheduler, state1) =>\n            {\n                _queue.Remove(si!); // NB: Assigned before function is invoked.\n                return action(scheduler, state1);\n            });\n\n            si = new ScheduledItem<DateTimeOffset, TState>(this, state, run, dueTime, Comparer);\n            _queue.Enqueue(si);\n\n            return si;\n        }\n    }\n}\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Concurrency/HistoricalScheduler.cs#L124-L160","documentation":"HistoricalScheduler.ScheduleAbsolute<TState>(state, dueTime, action) throws ArgumentNullException when action is null. The historical (virtual-time) scheduler wraps the action in a rescheduling closure before enqueuing it at the absolute due time, so it validates the delegate up front.","triggerScenarios":"Calling ScheduleAbsolute with a null Func<IScheduler, TState, IDisposable> — commonly in virtual-time test harnesses (TestScheduler-style code) where the action variable was conditionally assigned or a mock returned null.","commonSituations":"Rx test suites advancing virtual time with dynamically built actions; simulators that map events to scheduled work and produce a null callback for unmapped event types.","solutions":["Ensure the action delegate is non-null before calling ScheduleAbsolute.","In test harnesses, assert/mock setup produces a real delegate for every event kind.","Skip the schedule call when there is no work to run."],"exampleFix":"// before\nscheduler.ScheduleAbsolute(0, dueTime, _action); // _action may be null\n\n// after\nif (_action != null)\n    scheduler.ScheduleAbsolute(0, dueTime, _action);","handlingStrategy":"validation","validationCode":"if (action is null) throw new ArgumentNullException(nameof(action));\nhistoricalScheduler.ScheduleAbsolute(state, dueTime, action);","typeGuard":"static bool NonNull<TState>(Func<IScheduler, TState, IDisposable>? a) => a is not null;","tryCatchPattern":"try { historicalScheduler.ScheduleAbsolute(state, dueTime, action); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"action\")\n{\n    // fix test harness delegate mapping\n}","preventionTips":["In virtual-time tests, assert every event maps to a delegate","Avoid conditional assignment that leaves Func variables null","Use pattern matching/exhaustive switches to build actions"],"tags":["null-argument","scheduler","virtual-time"],"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"}