{"record":{"id":"aa680195f545c8b5","repo":"devlooped/moq","slug":"minimum-delay-has-to-be-lower-than-maximum-delay","errorCode":null,"errorMessage":"Minimum delay has to be lower than maximum delay.","messagePattern":"Minimum delay has to be lower than maximum delay\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Moq/ReturnsExtensions.cs","lineNumber":306,"sourceCode":"        internal static bool IsNullResult([NotNullWhen(false)] Delegate? valueFunction, Type resultType)\n#else\n        internal static bool IsNullResult(Delegate? valueFunction, Type resultType)\n#endif\n        {\n            if (valueFunction == null)\n            {\n                return !resultType.IsValueType || Nullable.GetUnderlyingType(resultType) != null;\n            }\n            else\n            {\n                return false;\n            }\n        }\n\n        static TimeSpan GetDelay(TimeSpan minDelay, TimeSpan maxDelay, Random random)\n        {\n            if (minDelay >= maxDelay)\n                throw new ArgumentException(Resources.MinDelayMustBeLessThanMaxDelay);\n\n            var min = (int)minDelay.Ticks;\n            var max = (int)maxDelay.Ticks;\n\n            return new TimeSpan(random.Next(min, max));\n        }\n\n        static IReturnsResult<TMock> DelayedResult<TMock, TResult>(IReturns<TMock, Task<TResult>> mock,\n            TResult value, TimeSpan delay)\n            where TMock : class\n        {\n            Guard.Positive(delay);\n\n            return mock.Returns(() =>\n            {\n                return Task.Delay(delay).ContinueWith(t => value);\n            });\n        }","sourceCodeStart":288,"sourceCodeEnd":324,"githubUrl":"https://github.com/devlooped/moq/blob/89a5be629c752960fe403e95ff583e4ae6f00542/src/Moq/ReturnsExtensions.cs#L288-L324","documentation":"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.","triggerScenarios":"Calling ReturnsAsync/ThrowsAsync with minDelay == maxDelay (e.g. TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1)) or minDelay > maxDelay (swapped arguments).","commonSituations":"Passing equal timespans to get a 'fixed' delay; accidentally swapping min and max parameters; computing delays from constants that happen to be equal.","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) { ... }"],"exampleFix":"// before\nmock.Setup(m => m.GetAsync()).ReturnsAsync(v, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1), random);\n// after\nmock.Setup(m => m.GetAsync()).ReturnsAsync(v, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), random);","handlingStrategy":"validation","validationCode":"if (minDelay >= maxDelay) throw new ArgumentException(\"minDelay must be strictly less than maxDelay\");","typeGuard":"bool IsValidDelayRange(TimeSpan min, TimeSpan max) => min < max;","tryCatchPattern":"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 */ }","preventionTips":["Assert min < max in test fixtures before setup","Use the fixed-delay overloads for equal min/max cases","Watch for swapped min/max arguments"],"tags":["moq","argument-range","timespan","randomness"],"backgroundTag":"value-out-of-range","analyzedSha":"89a5be629c752960fe403e95ff583e4ae6f00542","analyzedAt":"2026-09-16T05:31:39.496Z","contentChangedAt":"2026-09-16T05:31:39.496Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}