{"record":{"id":"75d3368e60f4c77c","repo":"dotnet/reactive","slug":"specified-argument-was-out-of-the-range-of-valid-values-75d336","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/Concurrency/ConcurrencyAbstractionLayerImpl.cs","lineNumber":35,"sourceCode":"        private sealed class WorkItem\n        {\n            public WorkItem(Action<object?> action, object? state)\n            {\n                Action = action;\n                State = state;\n            }\n\n            public Action<object?> Action { get; }\n            public object? State { get; }\n        }\n\n        public IDisposable StartTimer(Action<object?> action, object? state, TimeSpan dueTime) => new Timer(action, state, Normalize(dueTime));\n\n        public IDisposable StartPeriodicTimer(Action action, TimeSpan period)\n        {\n            if (period < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(period));\n            }\n\n            //\n            // The contract for periodic scheduling in Rx is that specifying TimeSpan.Zero as the period causes the scheduler to \n            // call back periodically as fast as possible, sequentially.\n            //\n            if (period == TimeSpan.Zero)\n            {\n                return new FastPeriodicTimer(action);\n            }\n\n            return new PeriodicTimer(action, period);\n        }\n\n        public IDisposable QueueUserWorkItem(Action<object?> action, object? state)\n        {\n            ThreadPool.QueueUserWorkItem(static itemObject =>\n            {","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Concurrency/ConcurrencyAbstractionLayerImpl.cs#L17-L53","documentation":"ConcurrencyAbstractionLayerImpl.StartPeriodicTimer throws ArgumentOutOfRangeException when the period is negative. Rx permits TimeSpan.Zero (meaning 'as fast as possible, sequentially') but a negative period is meaningless, so the abstraction layer rejects it before creating the underlying timer.","triggerScenarios":"Calling StartPeriodicTimer with a negative TimeSpan, typically from a computed value like TimeSpan.FromMilliseconds(-1) or a mis-subtracted duration, e.g. via SchedulePeriodic on DefaultScheduler.","commonSituations":"Computing intervals from subtracted DateTimes that produced a negative result, config files with negative polling intervals, or confusing dueTime semantics (negative dueTime is normalized to zero elsewhere, but period is not).","solutions":["Clamp or validate the period: if (period < TimeSpan.Zero) period = TimeSpan.Zero; before scheduling.","Use TimeSpan.Zero intentionally if you want sequential as-fast-as-possible callbacks; otherwise pass a positive interval.","Fix the upstream computation producing the negative TimeSpan (e.g. guard DateTime subtraction with Math.Max(TimeSpan.Zero, diff))."],"exampleFix":"// before\nvar period = nextRun - DateTime.Now; // can be negative\ncal.StartPeriodicTimer(tick, period);\n\n// after\nvar period = nextRun - DateTime.Now;\nif (period < TimeSpan.Zero) period = TimeSpan.Zero;\ncal.StartPeriodicTimer(tick, period);","handlingStrategy":"validation","validationCode":"if (period < TimeSpan.Zero) period = TimeSpan.Zero;\ncal.StartPeriodicTimer(action, period);","typeGuard":null,"tryCatchPattern":"try { cal.StartPeriodicTimer(action, period); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"period\") { /* clamp and retry with TimeSpan.Zero or positive period */ }","preventionTips":["Clamp computed intervals with Math.Max(TimeSpan.Zero, diff)","Validate configured intervals at startup","Remember Rx semantics: Zero = as-fast-as-possible, negatives are invalid"],"tags":["argument-out-of-range","timer","scheduling"],"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"}