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

TakeLast requires a non-negative `count` because it buffers the last N elements using a queue of bounded size. A negative count has no meaning, so the operator eagerly throws ArgumentOutOfRangeException naming `count` when called with count < 0.

Solutions

  1. Clamp with Math.Max(0, count) before calling TakeLast.
  2. Validate the count at the boundary (config, request) and reject negatives with a clear message.
  3. Fix the arithmetic producing the negative number.
  4. Note: count == 0 is valid and yields an empty sequence — only negatives throw.

Example fix

// before
var last = data.TakeLast(data.Count - removed);
// after
var last = data.TakeLast(Math.Max(0, data.Count - removed));
Defensive patterns

Strategy: validation

Validate before calling

if (count < 0) throw new ArgumentOutOfRangeException(nameof(count));
// or clamp: var safeCount = Math.Max(0, count);

Try / catch

try { var last = seq.TakeLast(count); }
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "count") { /* clamp and retry or fail fast */ }

Prevention

When it happens

Trigger: Calling `seq.TakeLast(-1)` or passing a computed length that can go negative, e.g. `TakeLast(list.Count - other.Count)` when other.Count > list.Count.

Common situations: Arithmetic on sizes taken from user input or config (pageSize = -1), off-by-one/diff calculations between two collections, or subtracting a baseline from a length.

Related errors


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

Appendix: source

Thrown at Ix.NET/Source/System.Interactive/System/Linq/Operators/TakeLast.cs:24

namespace System.Linq
{
    public static partial class EnumerableEx
    {
#if !(REFERENCE_ASSEMBLY && (NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER ))
        /// <summary>
        /// Returns a specified number of contiguous elements from the end of the sequence.
        /// </summary>
        /// <typeparam name="TSource">Source sequence element type.</typeparam>
        /// <param name="source">Source sequence.</param>
        /// <param name="count">The number of elements to take from the end of the sequence.</param>
        /// <returns>Sequence with the specified number of elements counting from the end of the source sequence.</returns>
        public static IEnumerable<TSource> TakeLast<TSource>(this IEnumerable<TSource> source, int count)
        {
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            if (count < 0)
                throw new ArgumentOutOfRangeException(nameof(count));

            return TakeLastCore(source, count);
        }

        private static IEnumerable<TSource> TakeLastCore<TSource>(IEnumerable<TSource> source, int count)
        {
            if (count == 0)
            {
                yield break;
            }

            var q = new Queue<TSource>(count);

            foreach (var item in source)
            {
                if (q.Count >= count)
                {
                    q.Dequeue();

View on GitHub (pinned to 94b5d5ab91)