devlooped/moq · error · ArgumentException
Delays have to be greater than zero to ensure an async…
Error message
Delays have to be greater than zero to ensure an async callback is used.
What it means
This ArgumentException from Guard.Positive enforces that a delay passed to Moq's async/timing APIs (e.g. Mock.Of/Delays inside SetupSequence or ReturnsAsync delay overloads, via Moq's Delay/Timeout features) is strictly greater than TimeSpan.Zero. A zero or negative delay cannot guarantee the async callback machinery is used.
Solutions
- Pass a strictly positive TimeSpan, e.g. TimeSpan.FromMilliseconds(1) or greater.
- Validate/normalize configured delay values before calling the API (clamp to a minimum of 1ms).
- If you truly need no delay, use the non-delayed overload of the API instead of passing zero.
Example fix
// before mock.SetupSequence(m => m.Load()).ReturnsAsync(data, TimeSpan.Zero); // after mock.SetupSequence(m => m.Load()).ReturnsAsync(data, TimeSpan.FromMilliseconds(50));
Defensive patterns
Strategy: validation
Validate before calling
if (delay <= TimeSpan.Zero)
throw new ArgumentException("Delay must be positive before calling Moq delay APIs");
Type guard
static bool IsPositiveDelay(TimeSpan d) => d > TimeSpan.Zero;
Try / catch
try { api.WithDelay(delay); }
catch (ArgumentException ex) when (ex.Message.Contains("Delays"))
{
delay = TimeSpan.FromMilliseconds(1); // retry with minimal positive delay
}
Prevention
- Never pass TimeSpan.Zero or default(TimeSpan) to delay parameters
- Clamp configured delays to a minimum positive value
- Check sign of computed/subtracted TimeSpans before use
When it happens
Trigger: Passing TimeSpan.Zero or a negative TimeSpan to an API whose guard is Guard.Positive(TimeSpan), such as delay-based callback/Returns overloads used with async setups.
Common situations: Computing a delay from config that resolves to 0; sign errors making the TimeSpan negative; default TimeSpan values (TimeSpan.Zero) passed through unmodified.
Related errors
- value (Argument is out of range)
- ArgumentNullException: Value cannot be null. (Parameter…
- Minimum delay has to be lower than maximum delay.
- ArgumentOutOfRangeException: callCount
- ArgumentOutOfRangeException: callCount
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/9e9100d100e16708.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Guard.cs:223
memberAccess.ToStringFixed()));
}
public static void IsMockable(Type type)
{
if (!type.IsMockable())
{
throw new NotSupportedException(
string.Format(
Resources.TypeNotMockable,
type.GetFormattedName()));
}
}
public static void Positive(TimeSpan delay)
{
if (delay <= TimeSpan.Zero)
{
throw new ArgumentException(Resources.DelaysMustBeGreaterThanZero);
}
}
public static void CanRead(PropertyInfo property)
{
if (!property.CanRead(out _))
{
throw new ArgumentException(string.Format(
CultureInfo.CurrentCulture,
Resources.PropertyGetNotFound,
property.DeclaringType!.Name, property.Name));
}
}
public static void CanWrite(PropertyInfo property)
{
if (!property.CanWrite(out _))
{View on GitHub (pinned to 89a5be629c)