devlooped/moq · error · ArgumentOutOfRangeException

ArgumentOutOfRangeException: callCountFrom (invalid range…

Error message

ArgumentOutOfRangeException: callCountFrom (invalid range bounds for Times.Between with Range.Exclusive)

What it means

Times.Between(from, to, Range.Exclusive) requires from >= 1 and to > from; the exclusive range must contain at least one valid value. Violating this throws ArgumentOutOfRangeException named callCountFrom. Additionally to - from must not equal 1, otherwise no integer lies strictly between them (that throws for callCountTo).

Solutions

  1. Ensure from >= 1 and to > from for the exclusive variant
  2. Use Range.Inclusive if zero should be a valid lower bound (with to >= from)
  3. Precompute and validate bounds before the call

Example fix

// before
mock.Verify(m => m.Foo(), Times.Between(0, 5, Range.Exclusive));
// after
mock.Verify(m => m.Foo(), Times.Between(1, 5, Range.Exclusive)); // or Range.Inclusive with 0
Defensive patterns

Strategy: validation

Validate before calling

if (from >= 1 && to > from)
    mock.Verify(m => m.Foo(), Times.Between(from, to, Range.Exclusive));

Prevention

When it happens

Trigger: Calling Times.Between(0, n, Range.Exclusive), Times.Between(negative, ...), or Between(a, b, Exclusive) where b <= a.

Common situations: Passing 0 as the lower bound assuming inclusive semantics; computing bounds dynamically where from ends up 0 or greater than to.

Related errors


AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16). Data as JSON: /api/errors/259c499d78f78bd6. Report an issue: GitHub.

Appendix: source

Thrown at src/Moq/Times.cs:119

        {
            return new Times(Kind.AtMostOnce, 0, 1);
        }

        /// <summary>
        ///   Specifies that a mocked method should be invoked between
        ///   <paramref name="callCountFrom"/> and <paramref name="callCountTo"/> times.
        /// </summary>
        /// <param name="callCountFrom">The minimum number of times.</param>
        /// <param name="callCountTo">The maximum number of times.</param>
        /// <param name="rangeKind">The kind of range. See <see cref="Range"/>.</param>
        /// <returns>An object defining the allowed number of invocations.</returns>
        public static Times Between(int callCountFrom, int callCountTo, Range rangeKind)
        {
            if (rangeKind == Range.Exclusive)
            {
                if (callCountFrom <= 0 || callCountTo <= callCountFrom)
                {
                    throw new ArgumentOutOfRangeException(nameof(callCountFrom));
                }

                if (callCountTo - callCountFrom == 1)
                {
                    throw new ArgumentOutOfRangeException(nameof(callCountTo));
                }

                return new Times(Kind.BetweenExclusive, callCountFrom + 1, callCountTo - 1);
            }

            if (callCountFrom < 0 || callCountTo < callCountFrom)
            {
                throw new ArgumentOutOfRangeException(nameof(callCountFrom));
            }

            return new Times(Kind.BetweenInclusive, callCountFrom, callCountTo);
        }

View on GitHub (pinned to 89a5be629c)