{"record":{"id":"0f227b9434e3c323","repo":"dotnet/reactive","slug":"throw-new-argumentoutofrangeexception-nameof-window","errorCode":null,"errorMessage":"throw new ArgumentOutOfRangeException(nameof(window));","messagePattern":"throw new ArgumentOutOfRangeException\\(nameof\\(window\\)\\);","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs","lineNumber":290,"sourceCode":"                throw new ArgumentNullException(nameof(selector));\n            if (window < TimeSpan.Zero)\n                throw new ArgumentOutOfRangeException(nameof(window));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(window, scheduler)), selector);\n        }\n\n        public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n            if (bufferSize < 0)\n                throw new ArgumentOutOfRangeException(nameof(bufferSize));\n            if (window < TimeSpan.Zero)\n                throw new ArgumentOutOfRangeException(nameof(window));\n\n            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(bufferSize, window)), selector);\n        }\n\n        public static IAsyncObservable<TResult> Replay<TSource, TResult>(this IAsyncObservable<TSource> source, Func<IAsyncObservable<TSource>, ValueTask<IAsyncObservable<TResult>>> selector, int bufferSize, TimeSpan window, IAsyncScheduler scheduler)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (selector == null)\n                throw new ArgumentNullException(nameof(selector));\n            if (bufferSize < 0)\n                throw new ArgumentOutOfRangeException(nameof(bufferSize));\n            if (window < TimeSpan.Zero)\n                throw new ArgumentOutOfRangeException(nameof(window));\n            if (scheduler == null)\n                throw new ArgumentNullException(nameof(scheduler));\n\n            return Multicast(source, () => new ValueTask<IAsyncSubject<TSource, TSource>>(new SequentialReplayAsyncSubject<TSource>(bufferSize, window, scheduler)), selector);","sourceCodeStart":272,"sourceCodeEnd":308,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Replay.cs#L272-L308","documentation":"The Replay(source, selector, bufferSize, window) operator validates the replay window and throws ArgumentOutOfRangeException when window is a negative TimeSpan. A negative expiration window for replayed items is meaningless, so the guard rejects it before constructing the SequentialReplayAsyncSubject.","triggerScenarios":"Calling AsyncObservable.Replay(source, selector, bufferSize, window) with a TimeSpan less than TimeSpan.Zero, e.g. a window parsed from a negative configured value or computed as an earlier timestamp minus a later one.","commonSituations":"Timespan parsed from config where the user entered '-5' intending seconds of magnitude; computing a duration by subtracting DateTime/Stopwatch values in the wrong order; unit tests passing TimeSpan.MinValue.","solutions":["Pass TimeSpan.Zero or a positive TimeSpan for the window.","Clamp before calling: window = window < TimeSpan.Zero ? TimeSpan.Zero : window.","Validate configured durations at load time (reject negatives with a clear message)."],"exampleFix":"// before\nvar replayed = AsyncObservable.Replay(source, sel, 10, window: TimeSpan.FromSeconds(-5));\n// after\nvar replayed = AsyncObservable.Replay(source, sel, 10, window: TimeSpan.FromSeconds(5));","handlingStrategy":"validation","validationCode":"if (window < TimeSpan.Zero) throw new ArgumentException(\"window must be non-negative\", nameof(window));","typeGuard":null,"tryCatchPattern":"try { var replayed = AsyncObservable.Replay(source, sel, bufferSize, window); } catch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"window\") { /* fall back to TimeSpan.Zero */ }","preventionTips":["Check duration arithmetic for reversed operands.","Validate TimeSpan config values at load time.","Use TimeSpan.Zero for 'no window'."],"tags":["argument-validation","timespan","reactive-extensions"],"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"}