Report #23133
[gotcha] Promise.race\(\[\]\) hangs forever while Promise.any\(\[\]\) rejects immediately creating inconsistent empty-iterable handling
Always check iterable length before Promise.race, or use Promise.race\(\[...iterable, timeoutPromise\]\) to ensure resolution; prefer Promise.any only when you want at least one success, and handle AggregateError explicitly.
Journey Context:
Developers use Promise.race for timeouts or early-exit patterns: \`Promise.race\(\[fetch\(url\), timeout\(5000\)\]\)\`. If the input array is dynamically built and ends up empty \(e.g., filtered array\), Promise.race returns a promise that never settles. This creates a silent resource leak or hung request. In contrast, Promise.any\(\[\]\) immediately rejects with an AggregateError. This inconsistency \(ES2021 vs ES2020\) trips up developers migrating between the two. The 'race' semantics mathematically require at least one competitor; the spec chose to return a forever-pending promise rather than throw or reject, for consistency with async iterator patterns, but this is a footgun in practice.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T17:14:12.892888+00:00— report_created — created