{"record":{"id":"090f5dd63b975798","repo":"dotnet/reactive","slug":"source-skiplast","errorCode":null,"errorMessage":"source","messagePattern":"source","errorType":"validation","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/SkipLast.cs","lineNumber":16,"sourceCode":"﻿// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT License.\n// See the LICENSE file in the project root for more information. \n\nusing System.Collections.Generic;\nusing System.Reactive.Concurrency;\nusing System.Threading.Tasks;\n\nnamespace System.Reactive.Linq\n{\n    public partial class AsyncObservable\n    {\n        public static IAsyncObservable<TSource> SkipLast<TSource>(this IAsyncObservable<TSource> source, int count)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (count < 0)\n                throw new ArgumentOutOfRangeException(nameof(count));\n\n            if (count == 0)\n            {\n                return source;\n            }\n\n            return CreateAsyncObservable<TSource>.From(\n                source,\n                count,\n                static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.SkipLast(observer, count)));\n        }\n\n\n        public static IAsyncObservable<TSource> SkipLast<TSource>(this IAsyncObservable<TSource> source, TimeSpan duration)\n        {\n            if (source == null)","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/SkipLast.cs#L1-L34","documentation":"SkipLast's first overload throws ArgumentNullException(\"source\") when the IAsyncObservable<TSource> it is called on is null. The library validates the source sequence at the public entry point before doing any work. Since SkipLast is an extension method, calling it on a null reference is possible in C# and produces this error instead of a NullReferenceException.","triggerScenarios":"Invoking nullSource.SkipLast(3) or SkipLast(null, 3) where the source IAsyncObservable is null, typically because a factory method or a previous operator returned null.","commonSituations":"A helper method returning null instead of an empty observable; conditional initialization leaving the sequence field unset; passing the result of a dictionary lookup that missed.","solutions":["Ensure the source sequence is non-null before calling SkipLast; use AsyncObservable.Empty<TSource>() as a fallback.","Fix the upstream producer so it never returns null (return an empty sequence instead).","Coalesce at the call site: source ?? AsyncObservable.Empty<T>().SkipLast(n)."],"exampleFix":"// before\nreturn cached.SkipLast(10); // cached may be null\n// after\nreturn (cached ?? AsyncObservable.Empty<TValue>()).SkipLast(10);","handlingStrategy":"validation","validationCode":"if (source == null) source = AsyncObservable.Empty<TSource>();\nvar res = source.SkipLast(count);","typeGuard":"static bool IsNonNull<T>(IAsyncObservable<T> s) => s != null;","tryCatchPattern":"try { var res = src.SkipLast(n); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"source\") { var res = AsyncObservable.Empty<TSource>(); }","preventionTips":["Never return null from sequence-producing methods; return AsyncObservable.Empty<T>().","Coalesce null sources at composition boundaries.","Enable nullable reference types to catch null observables at compile time."],"tags":["argument-null","observable","async-rx"],"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"}