{"record":{"id":"98822f1125721b2a","repo":"dotnet/reactive","slug":"duration-takelast","errorCode":null,"errorMessage":"duration","messagePattern":"duration","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeLast.cs","lineNumber":71,"sourceCode":"            return CreateAsyncObservable<TSource>.From(\n                source,\n                (count, scheduler),\n                static async (source, state, observer) =>\n                {\n                    var (sink, drain) = AsyncObserver.TakeLast(observer, state.count, state.scheduler);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, drain);\n                });\n        }\n\n        public static IAsyncObservable<TSource> TakeLast<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (duration < TimeSpan.Zero)\n                throw new ArgumentOutOfRangeException(nameof(duration));\n\n            if (duration == TimeSpan.Zero)\n            {\n                return Empty<TSource>();\n            }\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                duration,\n                static async (source, duration, observer) =>\n                {\n                    var (sink, drain) = AsyncObserver.TakeLast(observer, duration);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, drain);\n                });\n        }","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeLast.cs#L53-L89","documentation":"TakeLast(source, duration) throws ArgumentOutOfRangeException(\"duration\") when the TimeSpan is negative. A negative duration is meaningless for a 'take the last items within this window' operator, so the library rejects it up front with the parameter name.","triggerScenarios":"Calling source.TakeLast(TimeSpan.FromMilliseconds(-1)) or passing a duration computed from clock differences that came out negative.","commonSituations":"Computing a window as endTime - startTime where the values were swapped or the clock was non-monotonic; user/config-supplied durations parsed without sign validation; arithmetic on subtracted TimeSpans underflowing intent.","solutions":["Clamp or validate the duration to TimeSpan.Zero or greater before calling","Use TimeSpan.Zero explicitly when the intent is an empty result (the operator returns Empty for zero)","Fix the computation producing the negative TimeSpan (swapped operands, wrong clock)"],"exampleFix":"// before\nvar result = source.TakeLast(end - start); // end < start -> negative\n// after\nvar duration = end > start ? end - start : TimeSpan.Zero;\nvar result = source.TakeLast(duration);","handlingStrategy":"validation","validationCode":"if (duration < TimeSpan.Zero) duration = TimeSpan.Zero;\nvar result = source.TakeLast(duration);","typeGuard":"bool IsValidDuration(TimeSpan d) => d >= TimeSpan.Zero;","tryCatchPattern":"try { var r = source.TakeLast(duration); }\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"duration\") { var r = source.TakeLast(TimeSpan.Zero); }","preventionTips":["Validate user/config-supplied durations for sign at parse time","Use Math.Max(TimeSpan.Zero, computed) on derived windows","Keep a single helper for building TimeSpans from config"],"tags":["argument-range","rx","takelast","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"}