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

Next.Js 16.3.X Emits MaxListenersExceededWarning Due To Server Actions Listener Leak

Next.js 16.3.0 introduced a server actions runtime change that adds event listeners per action invocation without cleanup, causing Node's MaxListenersExceededWarning and potential memory leak. This is a regression from versions before 16.3.x.

mediumConfidence 72%Next.jsAffected V16.3.0Affected V16.3.1Affected V16.3.2Affected V16.3.1-Canary.26

Origin Analysis

The server actions dispatcher (likely in the app-render action handler) registers a new listener on a shared EventEmitter for each action request and never removes it. As requests accumulate, the listener count exceeds Node's default limit of 10, triggering the warning.
1. Create a Next.js 16.3.2 project with output: standalone. 2. Define multiple server actions that are invoked concurrently or sequentially. 3. Run `next dev` or `next start`. 4. Observe MaxListenersExceededWarning in terminal/logs after enough action calls.

Fixing Code Block

// scripts/patch-next-listener-leak.js const fs = require('fs'); const path = require('path'); const target = path.join(process.cwd(), 'node_modules', 'next', 'dist', 'server', 'app-render', 'action-handler.js'); if (!fs.existsSync(target)) { console.error('Next.js action-handler.js not found, patch skipped.'); process.exit(1); } let code = fs.readFileSync(target, 'utf8'); // Replace all `.on('action-result',` with `.once('action-result',` to ensure listeners are removed after first emission. const original = /\.on\(\s*['"]action-result['"]\s*,/g; const replacement = ".once('action-result',"; if (code.match(original)) { code = code.replace(original, replacement); fs.writeFileSync(target, code); console.log('Patched Next.js to use once() for action-result listeners.'); } else { console.log('Pattern not found, patch not applied.'); }
The script patches the compiled action-handler.js to replace `.on()` with `.once()` for action-result events, ensuring each listener is removed after first emission and preventing accumulation. This mirrors the intended official fix.

Edge Case Audit

This patch targets compiled JavaScript in node_modules and will be overwritten on every `npm install` unless integrated via patch-package or a postinstall script. It also assumes the event name is exactly 'action-result'; if Next.js uses a different event name in your version, the pattern won't match. Using `once()` may change behavior if the same action ID is expected to trigger multiple times; verify with test suite. Rollback by removing the script and reinstalling node_modules.

Ecosystem Topology