{"record":{"id":"0f7279e0d3f70570","repo":"dotnet/reactive","slug":"argumentoutofrangeexception-window-observable-binding","errorCode":null,"errorMessage":"ArgumentOutOfRangeException: window","messagePattern":"ArgumentOutOfRangeException: window","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs","lineNumber":535,"sourceCode":"        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <param name=\"source\">Source sequence whose elements will be multicasted through a single shared subscription.</param>\n        /// <param name=\"window\">Maximum time length of the replay buffer.</param>\n        /// <returns>A connectable observable sequence that shares a single subscription to the underlying sequence.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"window\"/> is less than TimeSpan.Zero.</exception>\n        /// <remarks>Subscribers will receive all the notifications of the source subject to the specified replay buffer trimming policy.</remarks>\n        /// <seealso cref=\"ReplaySubject{T}\"/>\n        public static IConnectableObservable<TSource> Replay<TSource>(this IObservable<TSource> source, TimeSpan window)\n        {\n            if (source == null)\n            {\n                throw new ArgumentNullException(nameof(source));\n            }\n\n            if (window < TimeSpan.Zero)\n            {\n                throw new ArgumentOutOfRangeException(nameof(window));\n            }\n\n            return s_impl.Replay(source, window);\n        }\n\n        /// <summary>\n        /// Returns an observable sequence that is the result of invoking the selector on a connectable observable sequence that shares a single subscription to the underlying sequence replaying notifications subject to a maximum time length for the replay buffer.\n        /// This operator is a specialization of Multicast using a <see cref=\"ReplaySubject{T}\"/>.\n        /// </summary>\n        /// <typeparam name=\"TSource\">The type of the elements in the source sequence.</typeparam>\n        /// <typeparam name=\"TResult\">The type of the elements in the result sequence.</typeparam>\n        /// <param name=\"source\">Source sequence whose elements will be multicasted through a single shared subscription.</param>\n        /// <param name=\"selector\">Selector function which can use the multicasted source sequence as many times as needed, without causing multiple subscriptions to the source sequence. Subscribers to the given source will receive all the notifications of the source subject to the specified replay buffer trimming policy.</param>\n        /// <param name=\"window\">Maximum time length of the replay buffer.</param>\n        /// <returns>An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function.</returns>\n        /// <exception cref=\"ArgumentNullException\"><paramref name=\"source\"/> or <paramref name=\"selector\"/> is null.</exception>\n        /// <exception cref=\"ArgumentOutOfRangeException\"><paramref name=\"window\"/> is less than TimeSpan.Zero.</exception>\n        /// <seealso cref=\"ReplaySubject{T}\"/>","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/Rx.NET/Source/src/System.Reactive/Linq/Observable.Binding.cs#L517-L553","documentation":"The time-based Replay overload requires the replay window to be a non-negative TimeSpan. System.Reactive validates arguments eagerly at call time, and throwing ArgumentOutOfRangeException for 'window' means a negative duration was supplied. Rx deliberately fails fast before creating any subscription infrastructure.","triggerScenarios":"Calling Observable.Replay(source, window) where window is a TimeSpan whose value is negative (e.g. TimeSpan.FromSeconds(-1), or a value computed from clock skew / subtraction where end < start).","commonSituations":"Computing a window by subtracting timestamps that came out inverted; misconfigured config values parsed into negative TimeSpans; unit tests passing TimeSpan.Zero minus something; sign errors when converting milliseconds.","solutions":["Check the window argument at the call site and ensure it is >= TimeSpan.Zero","If the window is computed, clamp or validate it before calling Replay (e.g. if (ts < TimeSpan.Zero) ts = TimeSpan.Zero)","Log or assert the computed TimeSpan to find where the negative value originates"],"exampleFix":"// before\nvar window = endTime - startTime;\nvar replayed = source.Replay(window);\n// after\nvar window = endTime - startTime;\nif (window < TimeSpan.Zero) window = TimeSpan.Zero;\nvar replayed = source.Replay(window);","handlingStrategy":"validation","validationCode":"if (window < TimeSpan.Zero)\n    throw new ArgumentOutOfRangeException(nameof(window), \"Replay window must be non-negative.\");","typeGuard":"static bool IsValidReplayWindow(TimeSpan window) => window >= TimeSpan.Zero;","tryCatchPattern":"try\n{\n    replayed = source.Replay(window);\n}\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"window\")\n{\n    logger.LogWarning(ex, \"Negative replay window {Window}; using default.\", window);\n    replayed = source.Replay(TimeSpan.Zero);\n}","preventionTips":["Validate computed TimeSpans before passing them to time-based Rx operators","Clamp durations derived from timestamp subtraction","Centralize TimeSpan parsing/config loading with range checks","Write unit tests covering negative and zero windows"],"tags":["rx","argument-validation","timespan"],"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-23T08:17:48.524Z"}