AI & Agent Dev Bug Sandbox logo
AI & Agent Dev Bug Sandbox
Back to Radar

Next.Js Crypto Wrappers Stack Across Realms Causing Memory Leak On Repeated Server Starts

Starting Next.js in a new JavaScript realm (e.g., Jest test files) wraps shared crypto functions without idempotency checks, leading to wrapper chains that retain previous realms and leak ~7.7 MB per realm.

highConfidence 95%Next.jsAffected V16.3.4Affected V16.4.0-Canary.47

Origin Analysis

The crypto wrapping logic in `node-environment-extensions/web-crypto.js` and `node-crypto.js` stores no marker on the patched functions and performs no check for existing wrappers. Since `globalThis.crypto` and the `node:crypto` module are shared across realms, each realm adds another wrapper layer, forming a chain that keeps all previous realms alive.
1. Clone https://github.com/lencioni/next-realm-leak-repro 2. Run `npm install` 3. Run `npm test` 4. Observe heap growth after each test file: wrapper count for `crypto.randomUUID` increases by 1 per file, and heap after GC grows from 35 MB to 119 MB over 12 files.

Fixing Code Block

Edge Case Audit

The fix assumes that the wrapper function is idempotent and that no other code modifies the same functions without preserving the marker. If a third-party library overrides the function without the marker, future calls to `wrapOnce` may overwrite it, causing unexpected behavior. The `Object.defineProperty` fallback sets `configurable: false`, which makes later rollback more difficult. To rollback, save references to the original functions before wrapping and restore them explicitly. Ensure that all wrapping sites consistently use `wrapOnce`; otherwise mixed approaches may still leak.

Ecosystem Topology