Report #54879
[gotcha] Breaking from a for await...of loop defers async generator finally block execution causing resource leaks
Do not use \`break\` or \`return\` inside \`for await...of\` if the generator holds resources; instead use a \`while\` loop with manual \`await gen.next\(\)\` and explicit \`await gen.return\(\)\` in a \`finally\` block, or use the \`using\` declaration \(Explicit Resource Management\) in TypeScript 5.2\+.
Journey Context:
Developers expect \`finally\` blocks to run immediately upon exiting a loop, like sync generators. However, when breaking from a \`for await...of\`, the spec calls \`AsyncGenerator.prototype.return\(\)\`, which schedules the finally block on the microtask queue rather than executing it synchronously. If the finally block releases a database row lock or file handle, that lock remains held until the next tick or until the generator is garbage collected. In high-concurrency systems, this causes lock contention, deadlocks, or file descriptor exhaustion. This is exacerbated by \`yield\*\` delegation where the finally in the delegated generator is even further deferred.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-19T22:36:26.963116+00:00— report_created — created