{"record":{"id":"e213dfe4e4c9f4bd","repo":"dotnet/reactive","slug":"specified-argument-was-out-of-the-range-of-valid-values-e213df","errorCode":null,"errorMessage":"Specified argument was out of the range of valid values. (Parameter 'period')","messagePattern":"Specified argument was out of the range of valid values\\. \\(Parameter 'period'\\)","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Concurrency/DispatcherScheduler.cs","lineNumber":184,"sourceCode":"\n            return d;\n        }\n\n        /// <summary>\n        /// Schedules a periodic piece of work on the dispatcher, using a <see cref=\"System.Windows.Threading.DispatcherTimer\"/> object.\n        /// </summary>\n        /// <typeparam name=\"TState\">The type of the state passed to the scheduled action.</typeparam>\n        /// <param name=\"state\">Initial state passed to the action upon the first iteration.</param>\n        /// <param name=\"period\">Period for running the work periodically.</param>\n        /// <param name=\"action\">Action to be executed, potentially updating the state.</param>\n        /// <returns>The disposable object used to cancel the scheduled recurring action (best effort).</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"action\"/> is <c>null</c>.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"period\"/> is less than <see cref=\"TimeSpan.Zero\"/>.</exception>\n        public IDisposable SchedulePeriodic<TState>(TState state, TimeSpan period, Func<TState, TState> action)\n        {\n            if (period < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(period));\n            }\n\n            if (action == null)\n            {\n                throw new ArgumentNullException(nameof(action));\n            }\n\n            var timer = new System.Windows.Threading.DispatcherTimer(Priority, Dispatcher);\n\n            var state1 = state;\n\n            timer.Tick += (s, e) =>\n            {\n                state1 = action(state1);\n            };\n\n            timer.Interval = period;\n            timer.Start();","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive.Wpf/System.Reactive.Concurrency/DispatcherScheduler.cs#L166-L202","documentation":"DispatcherScheduler.SchedulePeriodic throws ArgumentOutOfRangeException when the period is less than TimeSpan.Zero. A negative periodic interval is meaningless; zero is accepted by this check (the guard is strictly < Zero), but negative values are rejected before the action null-check.","triggerScenarios":"scheduler.SchedulePeriodic(state, TimeSpan.FromMilliseconds(-1), action) or a computed period from config/math that ends up negative (e.g. subtracting timestamps, misconfigured interval).","commonSituations":"Reading an interval from app config where the value is negative; computing period = next - now after `now` already passed; typos like FromSeconds(-1) in tests.","solutions":["Clamp the period before scheduling: if (period < TimeSpan.Zero) period = TimeSpan.Zero;.","Validate configuration values for polling intervals at startup and reject negatives early.","Use Math.Max(TimeSpan.Zero, computedPeriod) for derived periods."],"exampleFix":"// before\nscheduler.SchedulePeriodic(state, period, action); // period may be negative\n// after\nvar safePeriod = period < TimeSpan.Zero ? TimeSpan.Zero : period;\nscheduler.SchedulePeriodic(state, safePeriod, action);","handlingStrategy":"validation","validationCode":"if (period < TimeSpan.Zero) throw new InvalidOperationException($\"period must be >= TimeSpan.Zero, was {period}\");","typeGuard":"bool IsValidPeriod(TimeSpan p) => p >= TimeSpan.Zero;","tryCatchPattern":"try { scheduler.SchedulePeriodic(state, period, action); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"period\") { /* clamp and retry */ }","preventionTips":["Clamp computed periods with Math.Max(TimeSpan.Zero, period).","Validate configured intervals at startup.","Beware of signed arithmetic when deriving periods from timestamps."],"tags":["wpf","scheduler","argument-out-of-range","periodic-timer"],"backgroundTag":"argument-out-of-range","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"}