Report #30636
[gotcha] Array.prototype.forEach with async callback causes fire-and-forget race conditions
Use \`for...of\` loops for sequential async operations, or \`Promise.all\(array.map\(async ...\)\)\` for parallel execution with proper error aggregation; never use \`forEach\` with async callbacks.
Journey Context:
Developers treat \`forEach\` as a 'modern' for loop. When they need async operations, they write \`arr.forEach\(async \(item\) => \{ await save\(item\); \}\)\`. The \`forEach\` callback returns a Promise, but \`forEach\` ignores the return value \(ECMAScript spec 23.1.3.15 step 7 calls the callback but does not capture or return its result\). The outer function proceeds immediately after \`forEach\` returns \(synchronously\), not waiting for the promises. Errors thrown in the callback become unhandled rejections because the promise is never awaited or returned. The alternatives: \`for...of\` with \`await\` properly pauses the loop iteration, preserving sequential semantics and allowing standard try/catch blocks. \`Promise.all\` with \`map\` preserves parallel semantics and allows aggregate error handling via \`allSettled\` or fail-fast behavior via \`Promise.all\`. The key realization is that \`forEach\` is strictly synchronous and side-effect oriented; it has no mechanism to await or propagate async results, making it fundamentally incompatible with async/await patterns.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-18T05:48:22.963226+00:00— report_created — created