{"record":{"id":"074f86ec8b4d2116","repo":"dotnet/reactive","slug":"clock-takelast","errorCode":null,"errorMessage":"clock","messagePattern":"clock","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeLast.cs","lineNumber":98,"sourceCode":"                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        }\n\n        public static IAsyncObservable<TSource> TakeLast<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration, IClock clock)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (duration < TimeSpan.Zero)\n                throw new ArgumentOutOfRangeException(nameof(duration));\n            if (clock == null)\n                throw new ArgumentNullException(nameof(clock));\n\n            if (duration == TimeSpan.Zero)\n            {\n                return Empty<TSource>();\n            }\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                (duration, clock),\n                static async (source, state, observer) =>\n                {\n                    var (sink, drain) = AsyncObserver.TakeLast(observer, state.duration, state.clock);\n\n                    var subscription = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);\n\n                    return StableCompositeAsyncDisposable.Create(subscription, drain);\n                });\n        }","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/TakeLast.cs#L80-L116","documentation":"TakeLast(source, duration, clock) throws ArgumentNullException(\"clock\") because this overload requires an explicit IClock to define 'now' for the time window. Null is rejected eagerly with the parameter name instead of failing during subscription.","triggerScenarios":"Calling TakeLast(source, duration, (IClock)null), or passing a clock obtained from an accessor that returned null.","commonSituations":"Test code forgetting to supply a fake/test clock; DI container not registered for IClock; refactoring from the two-argument overload and adding a null clock placeholder.","solutions":["Pass a concrete IClock (system clock or test/virtual clock) instance","Use the TakeLast(source, duration) overload when the default clock suffices","Fix the clock provider/DI registration so it yields a non-null instance"],"exampleFix":"// before\nvar result = source.TakeLast(TimeSpan.FromSeconds(5), (IClock)null);\n// after\nvar result = source.TakeLast(TimeSpan.FromSeconds(5), clock); // injected IClock\n// or: var result = source.TakeLast(TimeSpan.FromSeconds(5));","handlingStrategy":"validation","validationCode":"if (clock is null) throw new InvalidOperationException(\"IClock must be resolved before calling TakeLast\");\nvar result = source.TakeLast(duration, clock);","typeGuard":"bool HasClock(IClock? c) => c is not null;","tryCatchPattern":"try { var r = source.TakeLast(duration, clock); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"clock\") { var r = source.TakeLast(duration); }","preventionTips":["Register IClock in DI at application startup","In tests, initialize the virtual clock before building queries","Use the default-clock overload when a custom clock adds no value"],"tags":["argument-null","rx","takelast","clock"],"backgroundTag":"null-argument","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"}