{"record":{"id":"72c544f189aa2b66","repo":"App-vNext/Polly","slug":"timeout","errorCode":null,"errorMessage":"timeout","messagePattern":"timeout","errorType":"exception","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"src/Polly/Timeout/AsyncTimeoutTResultSyntax.cs","lineNumber":165,"sourceCode":"        TimeoutValidator.ValidateTimeSpanTimeout(timeout);\n        return TimeoutAsync<TResult>(_ => timeout, TimeoutStrategy.Optimistic, onTimeoutAsync);\n    }\n\n    /// <summary>\n    /// Builds an <see cref=\"AsyncPolicy{TResult}\"/> that will wait asynchronously for a delegate to complete for a specified period of time. A <see cref=\"TimeoutRejectedException\"/> will be thrown if the delegate does not complete within the configured timeout.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of the result.</typeparam>\n    /// <param name=\"timeout\">The timeout.</param>\n    /// <param name=\"onTimeoutAsync\">An action to call on timeout, passing the execution context, the timeout applied, the <see cref=\"Task\"/> capturing the abandoned, timed-out action, and the captured <see cref=\"Exception\"/>.\n    /// <remarks>The Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.</remarks></param>\n    /// <returns>The policy instance.</returns>\n    /// <exception cref=\"ArgumentOutOfRangeException\">timeout;Value must be greater than zero.</exception>\n    /// <exception cref=\"ArgumentNullException\">Thrown when <paramref name=\"onTimeoutAsync\"/> is <see langword=\"null\"/>.</exception>\n    public static AsyncTimeoutPolicy<TResult> TimeoutAsync<TResult>(TimeSpan timeout, Func<Context, TimeSpan, Task, Exception, Task> onTimeoutAsync)\n    {\n        if (timeout <= TimeSpan.Zero)\n        {\n            throw new ArgumentOutOfRangeException(nameof(timeout));\n        }\n\n        return TimeoutAsync<TResult>(_ => timeout, TimeoutStrategy.Optimistic, onTimeoutAsync);\n    }\n\n    /// <summary>\n    /// Builds an <see cref=\"AsyncPolicy{TResult}\"/> that will wait asynchronously for a delegate to complete for a specified period of time. A <see cref=\"TimeoutRejectedException\"/> will be thrown if the delegate does not complete within the configured timeout.\n    /// </summary>\n    /// <typeparam name=\"TResult\">The type of the result.</typeparam>\n    /// <param name=\"timeout\">The timeout.</param>\n    /// <param name=\"timeoutStrategy\">The timeout strategy.</param>\n    /// <param name=\"onTimeoutAsync\">An action to call on timeout, passing the execution context, the timeout applied, and a <see cref=\"Task\"/> capturing the abandoned, timed-out action.\n    /// <remarks>The Task parameter will be null if the executed action responded cooperatively to cancellation before the policy timed it out.</remarks></param>\n    /// <returns>The policy instance.</returns>\n    /// <exception cref=\"ArgumentOutOfRangeException\">timeout;Value must be a positive TimeSpan (or Timeout.InfiniteTimeSpan to indicate no timeout).</exception>\n    /// <exception cref=\"ArgumentNullException\">Thrown when <paramref name=\"onTimeoutAsync\"/> is <see langword=\"null\"/>.</exception>\n    public static AsyncTimeoutPolicy<TResult> TimeoutAsync<TResult>(TimeSpan timeout, TimeoutStrategy timeoutStrategy, Func<Context, TimeSpan, Task, Task> onTimeoutAsync)\n    {","sourceCodeStart":147,"sourceCodeEnd":183,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly/Timeout/AsyncTimeoutTResultSyntax.cs#L147-L183","documentation":"Thrown by TimeoutAsync<TResult>(TimeSpan timeout, ...) (optimistic-only) when timeout <= TimeSpan.Zero. The guard rejects zero and negative spans; notably InfiniteTimeSpan is also rejected here even though other Polly surfaces accept it. Construction-time range check.","triggerScenarios":"Calling Policy.TimeoutAsync<TResult>(TimeSpan.Zero, onTimeoutAsync), a negative TimeSpan, or Timeout.InfiniteTimeSpan (which is negative). Misreading the doc — which mentions InfiniteTimeSpan only on the no-callback overload — leads developers to try it here.","commonSituations":"Passing default(TimeSpan) from an uninitialized struct; subtracting two DateTimes that yield negative; reading '00:00:00' from config; assuming InfiniteTimeSpan works on every overload.","solutions":["Pass a strictly positive TimeSpan, e.g. TimeSpan.FromSeconds(30).","If you genuinely need no timeout, omit the policy rather than passing InfiniteTimeSpan to this overload.","Validate upstream: if (timeout <= TimeSpan.Zero) fail fast with a clear config error."],"exampleFix":"// before\nPolicy.TimeoutAsync<MyResult>(TimeSpan.Zero, onTimeoutAsync);\nPolicy.TimeoutAsync<MyResult>(Timeout.InfiniteTimeSpan, onTimeoutAsync); // also throws\n\n// after\nPolicy.TimeoutAsync<MyResult>(TimeSpan.FromSeconds(30), onTimeoutAsync);","handlingStrategy":"validation","validationCode":"if (timeout <= TimeSpan.Zero) throw new ArgumentOutOfRangeException(nameof(timeout), \"must be > Zero; InfiniteTimeSpan not supported here\");\nvar policy = Policy.TimeoutAsync<TResult>(timeout, onTimeoutAsync);","typeGuard":"static bool IsValidSpan(TimeSpan t) => t > TimeSpan.Zero;","tryCatchPattern":null,"preventionTips":["Do not pass Timeout.InfiniteTimeSpan to this overload.","Validate spans parsed from config before constructing the policy.","Default(TimeSpan) is Zero — guard uninitialized struct fields."],"tags":["argument-out-of-range","validation","timeout","legacy-api","polly-v7"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}