devlooped/moq · error · ArgumentException
Minimum delay has to be lower than maximum delay.
Error message
Minimum delay has to be lower than maximum delay.
What it means
GetDelay requires minDelay to be strictly less than maxDelay; when minDelay >= maxDelay it throws ArgumentException('Minimum delay has to be lower than maximum delay.') because random.Next(min, max) would be undefined/empty for that range.
Solutions
- Ensure maxDelay is strictly greater than minDelay, e.g. (0s, 1s) instead of (1s, 1s)
- For a fixed delay use the ReturnsAsync/ThrowsAsync (value, TimeSpan delay) overloads instead of min/max
- Validate inputs before the call: if (minDelay < maxDelay) { ... }
Example fix
// before mock.Setup(m => m.GetAsync()).ReturnsAsync(v, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), random); // after mock.Setup(m => m.GetAsync()).ReturnsAsync(v, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), random);
Defensive patterns
Strategy: validation
Validate before calling
if (minDelay >= maxDelay) throw new ArgumentException("minDelay must be strictly less than maxDelay"); Type guard
bool IsValidDelayRange(TimeSpan min, TimeSpan max) => min < max;
Try / catch
try { mock.Setup(m => m.GetAsync()).ReturnsAsync(v, min, max, random); } catch (ArgumentException ex) when (ex.Message.Contains("Minimum delay")) { /* fix the range or use fixed delay */ } Prevention
- Assert min < max in test fixtures before setup
- Use the fixed-delay overloads for equal min/max cases
- Watch for swapped min/max arguments
When it happens
Trigger: Calling ReturnsAsync/ThrowsAsync with minDelay == maxDelay (e.g. TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) or minDelay > maxDelay (swapped arguments).
Common situations: Passing equal timespans to get a 'fixed' delay; accidentally swapping min and max parameters; computing delays from constants that happen to be equal.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Delays have to be greater than zero to ensure an async…
- ArgumentNullException: Value cannot be null. (Parameter…
- Unsupported expression
- Could not determine the correct positions for all argument…
- The return type of the last member shown above is not…
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/aa680195f545c8b5.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/ReturnsExtensions.cs:306
internal static bool IsNullResult([NotNullWhen(false)] Delegate? valueFunction, Type resultType)
#else
internal static bool IsNullResult(Delegate? valueFunction, Type resultType)
#endif
{
if (valueFunction == null)
{
return !resultType.IsValueType || Nullable.GetUnderlyingType(resultType) != null;
}
else
{
return false;
}
}
static TimeSpan GetDelay(TimeSpan minDelay, TimeSpan maxDelay, Random random)
{
if (minDelay >= maxDelay)
throw new ArgumentException(Resources.MinDelayMustBeLessThanMaxDelay);
var min = (int)minDelay.Ticks;
var max = (int)maxDelay.Ticks;
return new TimeSpan(random.Next(min, max));
}
static IReturnsResult<TMock> DelayedResult<TMock, TResult>(IReturns<TMock, Task<TResult>> mock,
TResult value, TimeSpan delay)
where TMock : class
{
Guard.Positive(delay);
return mock.Returns(() =>
{
return Task.Delay(delay).ContinueWith(t => value);
});
}View on GitHub (pinned to 89a5be629c)