Skip to content

Fix Infinity overflow in retry backoff calculation - #1246

Open
pavankumar-vh wants to merge 1 commit into
CodebuffAI:mainfrom
pavankumar-vh:fix/promise-retry-overflow-protection
Open

Fix Infinity overflow in retry backoff calculation#1246
pavankumar-vh wants to merge 1 commit into
CodebuffAI:mainfrom
pavankumar-vh:fix/promise-retry-overflow-protection

Conversation

@pavankumar-vh

Copy link
Copy Markdown

Overview

Fix Infinity overflow in retry backoff calculation in common/src/util/promise.ts.

Bug Description

The function used Math.pow(2, attempt) which can overflow to Infinity if attempt is large. Then Math.round(Infinity * jitter) returns Infinity, and setTimeout with Infinity would never fire, causing the retry to hang forever.

Fix

Added Number.isFinite() check to cap the delay at Number.MAX_SAFE_INTEGER.

Testing

No existing tests for this function, but the fix prevents infinite hangs.

Files Changed

  • common/src/util/promise.ts - Added overflow protection

Scope

This change only touches common/ which is an approved contribution area per the Contributing Guide.

The function used Math.pow(2, attempt) which can overflow to Infinity if attempt
is large. Then Math.round(Infinity * jitter) returns Infinity, and setTimeout
with Infinity would never fire, causing the retry to hang forever.

Added Number.isFinite() check to cap the delay at Number.MAX_SAFE_INTEGER.
@codebuff-team

Copy link
Copy Markdown
Contributor

Thanks for tracking this down — the overflow scenario is real: with enough retry attempts, Math.pow(2, attempt) does hit Infinity, and Math.round(Infinity * jitter) is NaN (not Infinity as stated, since Infinity * jitter where jitter is finite is Infinity, but the multiplication itself is fine — actually Infinity * 0.9 is Infinity, so Math.round gives Infinity, confirmed). setTimeout with Infinity per the HTML/Node spec clamps to a 1ms delay or fires immediately in most engines, not "hangs forever" — worth double-checking that claim, as it changes the severity of the bug you're describing.

On the fix itself: capping at Number.MAX_SAFE_INTEGER (~9e15 ms) is not really a usable delay either — setTimeout will clamp it to its internal max (2^31-1 ms, ~24.8 days) and the retry will still take an absurdly long time to fire. A more useful fix would cap baseDelayMs at some sane maximum backoff (e.g., a maxDelayMs parameter or a fixed ceiling like 30s), not just at whatever avoids Infinity/NaN.

This also has no accompanying test, and the repo doesn't have existing tests for withRetry per your own note — a maintainer would likely want at least a unit test asserting the delay is capped for large attempt counts before porting this.

Right instinct, but the numeric ceiling chosen doesn't actually solve the practical problem of overly long retry delays, and it needs a test to be portable as-is.

@codebuff-team codebuff-team added bot:triaged Classified by the community triage bot pr:needs-work Right idea, not mergeable as written labels Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bot:triaged Classified by the community triage bot pr:needs-work Right idea, not mergeable as written

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants