{"record":{"id":"e450ece3e7dbbc58","repo":"dotnet/reactive","slug":"scheduler-parameter-scheduler","errorCode":null,"errorMessage":"scheduler (Parameter 'scheduler')","messagePattern":"scheduler \\(Parameter 'scheduler'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs","lineNumber":185,"sourceCode":"        where TAbsolute : IComparable<TAbsolute>\n    {\n        private readonly IScheduler _scheduler;\n        private readonly TValue _state;\n        private readonly Func<IScheduler, TValue, IDisposable> _action;\n\n        /// <summary>\n        /// Creates a materialized work item.\n        /// </summary>\n        /// <param name=\"scheduler\">Recursive scheduler to invoke the scheduled action with.</param>\n        /// <param name=\"state\">State to pass to the scheduled action.</param>\n        /// <param name=\"action\">Scheduled action.</param>\n        /// <param name=\"dueTime\">Time at which to run the scheduled action.</param>\n        /// <param name=\"comparer\">Comparer used to compare work items based on their scheduled time.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"scheduler\"/> or <paramref name=\"action\"/> or <paramref name=\"comparer\"/> is <c>null</c>.</exception>\n        public ScheduledItem(IScheduler scheduler, TValue state, Func<IScheduler, TValue, IDisposable> action, TAbsolute dueTime, IComparer<TAbsolute> comparer)\n            : base(dueTime, comparer)\n        {\n            _scheduler = scheduler ?? throw new ArgumentNullException(nameof(scheduler));\n            _state = state;\n            _action = action ?? throw new ArgumentNullException(nameof(action));\n        }\n\n        /// <summary>\n        /// Creates a materialized work item.\n        /// </summary>\n        /// <param name=\"scheduler\">Recursive scheduler to invoke the scheduled action with.</param>\n        /// <param name=\"state\">State to pass to the scheduled action.</param>\n        /// <param name=\"action\">Scheduled action.</param>\n        /// <param name=\"dueTime\">Time at which to run the scheduled action.</param>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"scheduler\"/> or <paramref name=\"action\"/> is <c>null</c>.</exception>\n        public ScheduledItem(IScheduler scheduler, TValue state, Func<IScheduler, TValue, IDisposable> action, TAbsolute dueTime)\n            : this(scheduler, state, action, dueTime, Comparer<TAbsolute>.Default)\n        {\n        }\n\n        /// <summary>","sourceCodeStart":167,"sourceCodeEnd":203,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Concurrency/ScheduledItem.cs#L167-L203","documentation":"The public ScheduledItem<TAbsolute, TValue>.ctor(scheduler, state, action, dueTime, comparer) throws ArgumentNullException when scheduler is null. The stored IScheduler is used to invoke (and recursively reschedule) the work item, so it is essential; validation happens after the base comparer check.","triggerScenarios":"Constructing ScheduledItem directly (or via custom queue/scheduler code) with a null IScheduler argument, e.g. a scheduler property resolved lazily and still null.","commonSituations":"Custom PriorityQueue-based schedulers or test harnesses materializing work items; scheduling abstractions where the current scheduler is fetched from AsyncLocal/ThreadLocal storage that is empty; ported code passing null for a scheduler that an older API defaulted.","solutions":["Pass the scheduler instance on which the item will run (e.g. 'this' inside a scheduler implementation).","Fall back to Scheduler.Default or the appropriate scheduler instead of null.","Add a guard in the code that materializes ScheduledItem instances.","Fix AsyncLocal/ThreadLocal scheduler resolution so it returns a non-null default."],"exampleFix":"// before\nvar item = new ScheduledItem<DateTimeOffset, int>(currentScheduler /* null */, state, action, dueTime, comparer);\n// after\nvar scheduler = currentScheduler ?? Scheduler.Default;\nvar item = new ScheduledItem<DateTimeOffset, int>(scheduler, state, action, dueTime, comparer);","handlingStrategy":"validation","validationCode":"if (scheduler == null)\n    throw new ArgumentNullException(nameof(scheduler));","typeGuard":"bool HasScheduler(IScheduler s) => s is not null;","tryCatchPattern":"try\n{\n    var item = new ScheduledItem<DateTimeOffset, TState>(scheduler, state, action, dueTime, comparer);\n}\ncatch (ArgumentNullException ex) when (ex.ParamName == \"scheduler\")\n{\n    var item = new ScheduledItem<DateTimeOffset, TState>(Scheduler.Default, state, action, dueTime, comparer);\n}","preventionTips":["Inside scheduler implementations pass 'this' as the scheduler argument.","Fall back to Scheduler.Default for ambient-scheduler lookups that can be null.","Avoid null-returning AsyncLocal/ThreadLocal scheduler providers."],"tags":["rx","scheduler","argument-null","csharp"],"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"}