From 9a41144a65b79a4d445421112ca3aa1a3cc1ebbc Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Mon, 20 Oct 2025 14:53:37 -0400 Subject: [PATCH 1/4] use random port when forking if used by parent --- packages/next/src/cli/next-dev.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/cli/next-dev.ts b/packages/next/src/cli/next-dev.ts index 31b415c7580e4..6616c0fed212a 100644 --- a/packages/next/src/cli/next-dev.ts +++ b/packages/next/src/cli/next-dev.ts @@ -282,7 +282,7 @@ const nextDev = async ( if (nodeDebugType) { const address = getParsedDebugAddress() - address.port = address.port + 1 + address.port = address.port === 0 ? 0 : address.port + 1 nodeOptions[nodeDebugType] = formatDebugAddress(address) } From bc9e90d385478c762393e6546938300a9cdc6f6a Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Mon, 20 Oct 2025 21:04:12 -0400 Subject: [PATCH 2/4] add integration test for NODE_OPTIONS="--inspect=:0" --- packages/next/src/server/lib/start-server.ts | 7 ++++- packages/next/src/server/lib/utils.ts | 7 +++++ test/integration/cli/test/index.test.js | 29 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/start-server.ts b/packages/next/src/server/lib/start-server.ts index c31a74b5b7fe3..3a317d69764e7 100644 --- a/packages/next/src/server/lib/start-server.ts +++ b/packages/next/src/server/lib/start-server.ts @@ -26,6 +26,7 @@ import { RESTART_EXIT_CODE, getFormattedDebugAddress, getNodeDebugType, + isDebugAddressEphemeral, } from './utils' import { formatHostname } from './format-hostname' import { initialize } from './router-server' @@ -347,8 +348,12 @@ export async function startServer( if (nodeDebugType) { const formattedDebugAddress = getFormattedDebugAddress() + const isEphemeral = isDebugAddressEphemeral() Log.info( - `the --${nodeDebugType} option was detected, the Next.js router server should be inspected at ${formattedDebugAddress}.` + `the --${nodeDebugType} option was detected` + + (isEphemeral + ? '' + : `. the Next.js router server should be inspected at ${formattedDebugAddress}.`) ) } diff --git a/packages/next/src/server/lib/utils.ts b/packages/next/src/server/lib/utils.ts index ac8d62fb4356c..e11abd4bc4b3b 100644 --- a/packages/next/src/server/lib/utils.ts +++ b/packages/next/src/server/lib/utils.ts @@ -171,6 +171,13 @@ export const getParsedDebugAddress = (): DebugAddress => { return { host: undefined, port: parseInt(address, 10) } } +/** + * Checks if the debug address from `NODE_OPTIONS` specifies to use a random port (e.g., the port set to 0). + * + * @returns A boolean indicating whether or not the debug address is assigned to a random port. + */ +export const isDebugAddressEphemeral = () => getParsedDebugAddress()?.port === 0 + /** * Get the debug address from the `NODE_OPTIONS` environment variable and format * it into a string. diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index b373b9a76bb37..a94934b3ead79 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -571,6 +571,35 @@ describe('CLI Usage', () => { } }) + test("NODE_OPTIONS='--inspect=:0'", async () => { + const port = await findPort() + let output = '' + let errOutput = '' + const app = await runNextCommandDev( + [dirBasic, '--port', port], + undefined, + { + onStdout(msg) { + output += stripAnsi(msg) + }, + onStderr(msg) { + errOutput += stripAnsi(msg) + }, + env: { NODE_OPTIONS: '--inspect=:0' }, + } + ) + try { + await check(() => output, new RegExp(`http://localhost:${port}`)) + await check(() => errOutput, /Debugger listening on/) + expect(errOutput).not.toContain('address already in use') + expect(errOutput).toContain('Debugger listening on') + console.log(output) + expect(output).toContain('the --inspect option was detected') + } finally { + await killApp(app) + } + }) + test("NODE_OPTIONS='--require=file with spaces to-require-with-node-require-option.js'", async () => { const port = await findPort() let output = '' From c5d0dce984269b567841f73566e38f33e4a0f24e Mon Sep 17 00:00:00 2001 From: Caleb Webber Date: Mon, 20 Oct 2025 21:06:40 -0400 Subject: [PATCH 3/4] undo change in punctuation --- packages/next/src/server/lib/start-server.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/start-server.ts b/packages/next/src/server/lib/start-server.ts index 3a317d69764e7..fbade93a589e9 100644 --- a/packages/next/src/server/lib/start-server.ts +++ b/packages/next/src/server/lib/start-server.ts @@ -353,7 +353,7 @@ export async function startServer( `the --${nodeDebugType} option was detected` + (isEphemeral ? '' - : `. the Next.js router server should be inspected at ${formattedDebugAddress}.`) + : `, the Next.js router server should be inspected at ${formattedDebugAddress}.`) ) } From 8918cd52d58203911b4b303510296ecb4e2a310b Mon Sep 17 00:00:00 2001 From: Sebastian Sebbie Silbermann Date: Tue, 21 Oct 2025 16:50:59 +0200 Subject: [PATCH 4/4] Use random port in static worker if the parent also picked a random port --- packages/next/src/lib/worker.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/next/src/lib/worker.ts b/packages/next/src/lib/worker.ts index bbbf6aeea5ba5..0c09f18c1d88e 100644 --- a/packages/next/src/lib/worker.ts +++ b/packages/next/src/lib/worker.ts @@ -85,10 +85,12 @@ export class Worker { if (nodeDebugType) { const address = getParsedDebugAddress() address.port = - address.port + - // current process runs on `address.port` - 1 + - debuggerPortOffset + address.port === 0 + ? 0 + : address.port + + // current process runs on `address.port` + 1 + + debuggerPortOffset nodeOptions[nodeDebugType] = formatDebugAddress(address) } }