dotnet/reactive · error · ArgumentNullException
Value cannot be null. (Parameter 'skip')
Error message
Value cannot be null. (Parameter 'skip')
What it means
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.
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.
Example fix
// before
var sliding = source.Buffer(10, overlap); // overlap == 10 -> skip == 0
// after
var skip = count - overlap;
if (skip <= 0) throw new ArgumentException("overlap must be smaller than count");
var sliding = source.Buffer(count, skip); Defensive patterns
Strategy: validation
Validate before calling
var skip = count - overlap;
if (skip <= 0) throw new ArgumentException("overlap must be smaller than count so skip >= 1", nameof(overlap)); Type guard
bool IsValidSkip(int skip) => skip > 0;
Try / catch
try { var sliding = source.Buffer(count, skip); }
catch (ArgumentNullException ex) when (ex.ParamName == "skip") { throw new InvalidOperationException("skip must be >= 1; use skip == count for non-overlapping buffers", ex); } Prevention
- 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
When it happens
Trigger: 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.
Common situations: Implementing sliding windows where overlap is configurable — overlap == count makes skip 0; UI or API inputs accepting 0 for 'no advance'; uninitialized int fields.
Related errors
- Value cannot be null. (Parameter 'count')
- Value cannot be null. (Parameter 'timeSpan')
- Value cannot be null. (Parameter 'source')
- Value cannot be null. (Parameter 'onErrorAsync')
- Value cannot be null. (Parameter 'onCompletedAsync')
AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15).
Data as JSON: /api/errors/0daa3336c332ffda.
Report an issue: GitHub.
Appendix: source
Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Buffer.cs:35
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentNullException(nameof(count));
return CreateAsyncObservable<IList<TSource>>.From(
source,
count,
static (source, count, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, count)));
}
public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, int count, int skip)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (count <= 0)
throw new ArgumentNullException(nameof(count));
if (skip <= 0)
throw new ArgumentNullException(nameof(skip));
return CreateAsyncObservable<IList<TSource>>.From(
source,
(count, skip),
static (source, state, observer) => source.SubscribeSafeAsync(AsyncObserver.Buffer(observer, state.count, state.skip)));
}
public static IAsyncObservable<IList<TSource>> Buffer<TSource>(this IAsyncObservable<TSource> source, TimeSpan timeSpan)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (timeSpan < TimeSpan.Zero)
throw new ArgumentNullException(nameof(timeSpan));
return CreateAsyncObservable<IList<TSource>>.From(
source,
timeSpan,
static async (source, timeSpan, observer) =>View on GitHub (pinned to 94b5d5ab91)