{"record":{"id":"0daa3336c332ffda","repo":"dotnet/reactive","slug":"value-cannot-be-null-parameter-skip","errorCode":null,"errorMessage":"Value cannot be null. (Parameter 'skip')","messagePattern":"Value cannot be null\\. \\(Parameter 'skip'\\)","errorType":"exception","errorClass":"ArgumentNullException","httpStatus":null,"severity":"error","filePath":"AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs","lineNumber":35,"sourceCode":"            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (count <= 0)\n                throw new ArgumentNullException(nameof(count));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                count,\n                static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, count)));\n        }\n\n        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, int count, int skip)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (count <= 0)\n                throw new ArgumentNullException(nameof(count));\n            if (skip <= 0)\n                throw new ArgumentNullException(nameof(skip));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                (count, skip),\n                static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, state.count, state.skip)));\n        }\n\n        public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan)\n        {\n            if (source == null)\n                throw new ArgumentNullException(nameof(source));\n            if (timeSpan < TimeSpan.Zero)\n                throw new ArgumentNullException(nameof(timeSpan));\n\n            return CreateAsyncObservable<IList<TSource>>.From(\n                source,\n                timeSpan,\n                static async (source, timeSpan, observer) =>","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/dotnet/reactive/blob/94b5d5ab912789f5abe9a72138a25bbd716fe59c/AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs#L17-L53","documentation":"Buffer<TSource>(source, count, skip) throws ArgumentNullException(nameof(skip)) when skip <= 0. The skip value controls how far the buffer window advances between buffers; a non-positive skip would stall or corrupt windowing, so it is rejected. The library reports it as ArgumentNullException with parameter 'skip' even though it is semantically a range error.","triggerScenarios":"Calling source.Buffer(count, 0) or source.Buffer(count, negative); skip computed from config or arithmetic (e.g. count - overlap where overlap >= count); accidentally passing 0 because 'no skip' seemed like 0 instead of skip == count.","commonSituations":"Implementing sliding windows where overlap is configurable — overlap == count makes skip 0; UI or API inputs accepting 0 for 'no advance'; uninitialized int fields.","solutions":["Pass skip >= 1; clamp: skip = Math.Max(1, skip).","If you wanted non-overlapping buffers, pass skip equal to count, not 0 (source.Buffer(count, count)).","Validate overlap/skip configuration before composing the pipeline and reject <= 0 with a domain error."],"exampleFix":"// before\nvar sliding = source.Buffer(10, overlap); // overlap == 10 -> skip == 0\n// after\nvar skip = count - overlap;\nif (skip <= 0) throw new ArgumentException(\"overlap must be smaller than count\");\nvar sliding = source.Buffer(count, skip);","handlingStrategy":"validation","validationCode":"var skip = count - overlap;\nif (skip <= 0) throw new ArgumentException(\"overlap must be smaller than count so skip >= 1\", nameof(overlap));","typeGuard":"bool IsValidSkip(int skip) => skip > 0;","tryCatchPattern":"try { var sliding = source.Buffer(count, skip); }\ncatch (ArgumentNullException ex) when (ex.ParamName == \"skip\") { throw new InvalidOperationException(\"skip must be >= 1; use skip == count for non-overlapping buffers\", ex); }","preventionTips":["Remember skip == 0 is invalid even for 'no advance' semantics — pass skip equal to count instead","Validate overlap configuration against count before composing","Clamp: skip = Math.Max(1, skip) as a last-resort guard"],"tags":["argumentnull","argument-range","asyncrx","buffer","skip"],"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"}