devlooped/moq · error · ArgumentOutOfRangeException
ArgumentOutOfRangeException: callCount
Error message
ArgumentOutOfRangeException: callCount ('{0}' value must be greater than or equal to '0'). What it means
AtMost builds the upper bound of an invocation-count constraint used in Verify, so a negative count is meaningless and would invert the allowed range (0..callCount), silently breaking verification; the factory rejects it eagerly at construction. The throw site is a plain argument-validation guard: the faulty input is an int callCount argument less than zero, e.g. mock.Verify(m => m.Foo(), Times.AtMost(-1)), often from a computed count that went below zero. Note this site throws the plain ArgumentOutOfRangeException(nameof(callCount)); the richer formatted message ('{0}' value must be greater than or equal to '0') belongs to a different constructor overload in the same type.
Solutions
- Validate/clamp the count to >= 0 before calling AtMost
- Replace sentinel -1 with a proper optional/nullable representation and choose Times accordingly
- Use Times.AtMost(0) or Times.Never for zero expected calls
Example fix
// before mock.Verify(m => m.Foo(), Times.AtMost(limit)); // limit default -1 // after mock.Verify(m => m.Foo(), limit < 0 ? Times.Never : Times.AtMost(limit));
Defensive patterns
Strategy: validation
Validate before calling
if (maxCalls >= 0)
mock.Verify(m => m.Foo(), Times.AtMost(maxCalls)); Prevention
- Clamp upper bounds to >= 0
- Replace -1 sentinels with nullable ints
- Use AtMost(0)/Never for zero expected calls
When it happens
Trigger: Calling Times.AtMost with a negative number, e.g. from an off-by-one subtraction, a default of -1 meaning 'unset', or user-supplied config.
Common situations: Uninitialized integer defaults (-1) fed into AtMost; subtracting counts; parsing configuration where sentinel negatives leak through.
Related errors
- ArgumentOutOfRangeException: callCount
- ArgumentOutOfRangeException: callCountFrom (invalid range…
- ArgumentOutOfRangeException: callCountTo (invalid range…
- ArgumentOutOfRangeException: callCountFrom (invalid range…
- Delays have to be greater than zero to ensure an async…
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/cc796730e9ce02a9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Times.cs:90
/// Specifies that a mocked method should be invoked one time as minimum.
/// </summary>
/// <returns>An object defining the allowed number of invocations.</returns>
public static Times AtLeastOnce()
{
return new Times(Kind.AtLeastOnce, 1, int.MaxValue);
}
/// <summary>
/// Specifies that a mocked method should be invoked <paramref name="callCount"/> times
/// as maximum.
/// </summary>
/// <param name="callCount">The maximum number of times.</param>
/// <returns>An object defining the allowed number of invocations.</returns>
public static Times AtMost(int callCount)
{
if (callCount < 0)
{
throw new ArgumentOutOfRangeException(nameof(callCount));
}
return new Times(Kind.AtMost, 0, callCount);
}
/// <summary>
/// Specifies that a mocked method should be invoked one time as maximum.
/// </summary>
/// <returns>An object defining the allowed number of invocations.</returns>
public static Times AtMostOnce()
{
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>View on GitHub (pinned to 89a5be629c)