Skip to content

fix(core): clamp large timer delays to TIMEOUT_MAX instead of 1ms#32860

Open
bartlomieju wants to merge 1 commit intodenoland:mainfrom
bartlomieju:fix/abort-signal-timeout-large-delay
Open

fix(core): clamp large timer delays to TIMEOUT_MAX instead of 1ms#32860
bartlomieju wants to merge 1 commit intodenoland:mainfrom
bartlomieju:fix/abort-signal-timeout-large-delay

Conversation

@bartlomieju
Copy link
Member

Summary

AbortSignal.timeout(2 ** 53 - 1) was aborting instantly because
the JS timer clamping logic treated values above TIMEOUT_MAX (2^31-1)
the same as values below 1 — both got set to 1ms.

Fix: clamp values above TIMEOUT_MAX to TIMEOUT_MAX (~24.8 days)
instead of 1ms. Values below 1 (NaN, negative, zero) still clamp to 1ms.

Regression from #32543 (timer refactor moving processing from Rust to JS).

Closes #32858

Test plan

  • ./x test-unit timers passes
  • Manual: AbortSignal.timeout(2**53-1) no longer aborts instantly

🤖 Generated with Claude Code

`AbortSignal.timeout(2 ** 53 - 1)` was aborting instantly because
values above TIMEOUT_MAX (2^31-1) were clamped to 1ms. Now they
clamp to TIMEOUT_MAX (~24.8 days) instead.

Closes denoland#32858

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@bartlomieju
Copy link
Member Author

Worth noting that this diverges from Node.js behavior: Node.js clamps values above TIMEOUT_MAX to 1ms (and emits a TimeoutOverflowWarning), while this PR clamps to TIMEOUT_MAX (~24.8 days).

// Node.js (lib/internal/timers.js):
// setTimeout(fn, 2**32) → fires after 1ms + warning

// Deno (this PR):
// setTimeout(fn, 2**32) → fires after ~24.8 days

The Deno behavior is arguably more intuitive (a huge timeout stays huge rather than becoming instant), but it's a conscious compat difference. Might be worth a brief comment in the code noting this is intentional.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AbortSignal.timeout(2 ** 53 - 1) instantly aborts

1 participant