Skip to content

[copilot-finds] Bug: RetryPolicy constructor silently accepts NaN and Infinity, enabling infinite retries #230

@github-actions

Description

@github-actions

Problem

RetryPolicy validates constructor parameters using comparison operators (<=, <) that silently accept NaN and Infinity because JavaScript NaN comparisons always return false.

File: packages/durabletask-js/src/task/retry/retry-policy.ts, lines 67-94

For example:

// NaN <= 0 evaluates to false, so NaN passes this validation!
if (maxNumberOfAttempts <= 0) {
  throw new Error("maxNumberOfAttempts must be greater than zero");
}

Root Cause

JavaScript NaN comparison semantics: NaN <= 0, NaN < 1.0, and NaN >= x all return false. This means every comparison-based guard in the constructor is bypassed when NaN is passed.

This can happen when users compute retry parameters from external sources:

const maxAttempts = parseInt(process.env.MAX_RETRIES!); // NaN if env var is undefined

Impact

  • maxNumberOfAttempts: NaN — Most severe. The check attemptCount >= maxNumberOfAttempts in RetryableTask.computeNextDelayInMilliseconds() always returns false when maxNumberOfAttempts is NaN, causing infinite retries that never stop.
  • firstRetryIntervalInMilliseconds: NaN — Produces NaN timer delays, creating timers with Invalid Date.
  • backoffCoefficient: NaN — Produces NaN delay values on all retry calculations.
  • Infinity values — Similar issues: Infinity maxNumberOfAttempts allows unlimited retries, Infinity intervals create timers that cannot fire.

Proposed Fix

Add Number.isFinite() guards before all comparison checks in the RetryPolicy constructor. Number.isFinite() returns false for NaN, Infinity, and -Infinity, catching all invalid numeric values.

Metadata

Metadata

Assignees

No one assigned

    Labels

    copilot-findsFindings from daily automated code review agent

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions