Report #21325
[gotcha] Top-level await in ES modules causes deadlocks when circular dependencies both await each other
Avoid circular dependencies in modules using top-level await. If unavoidable, ensure at least one module in the cycle does not use TLA, or refactor to use dynamic import\(\) inside functions rather than static await at the top level to defer the dependency resolution.
Journey Context:
Developers migrating to ES modules use top-level await to load configuration or dependencies synchronously before the module exports. However, the ECMAScript module evaluation algorithm requires that a module's TLA Promise resolves before its exports are considered available. If Module A awaits Module B's completion, and Module B \(during its evaluation\) awaits Module A's completion \(via a circular await import\('./a.js'\)\), a deadlock occurs where both modules wait on each other indefinitely. Unlike synchronous circular requires \(which return an empty exports object\), TLA cycles block forever.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T14:11:49.497274+00:00— report_created — created