dotnet/reactive · error · ArgumentOutOfRangeException

Specified argument was out of the range of valid values…

Error message

Specified argument was out of the range of valid values. (Parameter 'count')

What it means

This ArgumentOutOfRangeException is thrown by the count-based Window helper when count is zero or negative. count defines how many source elements go into each window, so only positive integers are valid. The check runs immediately at call time, before subscription.

Solutions

  1. Pass a positive count (>= 1) to Window.
  2. Validate/clamp the value first: if (count < 1) throw new ArgumentException(...); or count = Math.Max(1, count).
  3. Fix the configuration source so the batch/window size is a positive number.
  4. Ensure user input is parsed and validated before reaching the operator.

Example fix

// before
var size = config.BatchSize; // 0
var windows = source.Window(size);
// after
var size = Math.Max(1, config.BatchSize);
var windows = source.Window(size);
Defensive patterns

Strategy: validation

Validate before calling

if (count < 1) throw new ArgumentOutOfRangeException(nameof(count), count, "Window count must be positive.");
// or clamp: count = Math.Max(1, count);

Type guard

bool IsValidCount(int count) => count > 0;

Try / catch

try
{
    var windows = source.Window(count);
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "count")
{
    count = DefaultWindowSize; // e.g. 10
}

Prevention

When it happens

Trigger: Calling Window(source, count) or Window(observer, subscription, count[, skip]) with count <= 0, e.g. a computed value of 0 from an empty config or a division result.

Common situations: Batch-size configuration defaulting to 0; parsing user input without validating positivity; arithmetic that underflows to 0 or negative when the sequence is empty.

Related errors


AI-assisted analysis of dotnet/reactive@94b5d5ab91 (2026-09-15). Data as JSON: /api/errors/5063bfc29a3be73a. Report an issue: GitHub.

Appendix: source

Thrown at AsyncRx.NET/System.Reactive.Async/Linq/Operators/Window.cs:225

            var inner = await source.SubscribeSafeAsync(sink).ConfigureAwait(false);
            await d.AssignAsync(inner).ConfigureAwait(false);

            return subscription;
        }
    }

    public partial class AsyncObserver
    {
        public static (IAsyncObserver<TSource>, IAsyncDisposable) Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, int count) => Window(observer, subscription, count, count);

        public static (IAsyncObserver<TSource>, IAsyncDisposable) Window<TSource>(IAsyncObserver<IAsyncObservable<TSource>> observer, IAsyncDisposable subscription, int count, int skip)
        {
            if (observer == null)
                throw new ArgumentNullException(nameof(observer));
            if (subscription == null)
                throw new ArgumentNullException(nameof(subscription));
            if (count <= 0)
                throw new ArgumentOutOfRangeException(nameof(count));
            if (skip <= 0)
                throw new ArgumentOutOfRangeException(nameof(skip));

            var refCount = new RefCountAsyncDisposable(subscription);

            var queue = new Queue<IAsyncSubject<TSource>>();
            var n = 0;

            return
                (
                    Create<TSource>
                    (
                        async x =>
                        {
                            foreach (var window in queue)
                            {
                                await window.OnNextAsync(x).ConfigureAwait(false);
                            }

View on GitHub (pinned to 94b5d5ab91)