devlooped/moq · error · ArgumentOutOfRangeException

ArgumentOutOfRangeException: callCountFrom (invalid range…

Error message

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

What it means

Times.Between with Range.Inclusive requires from >= 0 and to >= from. When from is negative or greater than to, ArgumentOutOfRangeException named callCountFrom is thrown (the parameter deemed invalid is reported as callCountFrom for both order violations in this branch).

Solutions

  1. Ensure 0 <= from <= to before calling; swap min/max of computed values with Math.Min/Math.Max
  2. Use the Inclusive range when 0 should be allowed as a lower bound
  3. Add a precondition check on the computed bounds

Example fix

// before
mock.Verify(m => m.Foo(), Times.Between(max, min, Range.Inclusive));
// after
mock.Verify(m => m.Foo(), Times.Between(Math.Min(min, max), Math.Max(min, max), Range.Inclusive));
Defensive patterns

Strategy: validation

Validate before calling

var lo = Math.Min(from, to);
var hi = Math.Max(from, to);
if (lo >= 0)
    mock.Verify(m => m.Foo(), Times.Between(lo, hi, Range.Inclusive));

Prevention

When it happens

Trigger: Times.Between(-1, 5, Range.Inclusive) or Times.Between(5, 2, Range.Inclusive) — inverted or negative bounds.

Common situations: Swapping from/to arguments; computing bounds where a lower estimate exceeds the upper; negative sentinel values leaking in.

Related errors


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

Appendix: source

Thrown at src/Moq/Times.cs:132

        {
            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);
        }

        /// <summary>
        ///   Specifies that a mocked method should be invoked exactly
        ///   <paramref name="callCount"/> times.
        /// </summary>
        /// <param name="callCount">The times that a method or property can be called.</param>
        /// <returns>An object defining the allowed number of invocations.</returns>
        public static Times Exactly(int callCount)
        {
            if (callCount < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(callCount));
            }

View on GitHub (pinned to 89a5be629c)