From 86066045eabbb5d15734755df4f315a2c8ced243 Mon Sep 17 00:00:00 2001 From: avivkeller Date: Tue, 4 Aug 2026 15:06:06 -0400 Subject: [PATCH 1/9] cli: add No-Op `--experimental-repl-await` Signed-off-by: Aviv Keller PR-URL: https://github.com/nodejs/node/pull/64986 Reviewed-By: Antoine du Hamel --- doc/api/cli.md | 1 + doc/node.1 | 2 ++ src/node_options.cc | 1 + 3 files changed, 4 insertions(+) diff --git a/doc/api/cli.md b/doc/api/cli.md index fc0a194f8dbd..514af04c02cd 100644 --- a/doc/api/cli.md +++ b/doc/api/cli.md @@ -3888,6 +3888,7 @@ one is included in the list below. * `--experimental-package-map` * `--experimental-print-required-tla` * `--experimental-quic` +* `--experimental-repl-await` * `--experimental-require-module` * `--experimental-shadow-realm` * `--experimental-specifier-resolution` diff --git a/doc/node.1 b/doc/node.1 index 2155c361477d..dd541051de28 100644 --- a/doc/node.1 +++ b/doc/node.1 @@ -2007,6 +2007,8 @@ one is included in the list below. .It \fB--experimental-quic\fR .It +\fB--experimental-repl-await\fR +.It \fB--experimental-require-module\fR .It \fB--experimental-shadow-realm\fR diff --git a/src/node_options.cc b/src/node_options.cc index fd16fac426f6..c743a20c31bf 100644 --- a/src/node_options.cc +++ b/src/node_options.cc @@ -741,6 +741,7 @@ EnvironmentOptionsParser::EnvironmentOptionsParser() { kAllowedInEnvvar, false, OptionNamespaces::kPermissionNamespace); + AddOption("--experimental-repl-await", "", NoOp{}, kAllowedInEnvvar); AddOption("--experimental-vm-modules", "experimental ES Module support in vm module", BOOL_FIELD(experimental_vm_modules), From 86c871eceda3cdbda53c870851cf6582b928550d Mon Sep 17 00:00:00 2001 From: Phillip Markert Date: Sat, 15 Aug 2026 17:59:44 -0400 Subject: [PATCH 2/9] test: replace `forEach()` with `for...of` in parallel tests Replace `Array.prototype.forEach()` with `for...of` loops across 17 tests in `test/parallel`, so each loop body reads as a plain statement rather than an arrow callback. None of the iterated values are sparse arrays, the one case where `forEach` and `for...of` genuinely differ, so both constructs visit the same elements in the same order. No callback relied on `this`, an early return, or async behaviour, and the number of assertions run in each file is unchanged. Signed-off-by: Phillip Markert PR-URL: https://github.com/nodejs/node/pull/65272 Reviewed-By: James M Snell Reviewed-By: Aviv Keller Reviewed-By: Ethan Arrowood --- test/parallel/test-btoa-atob.js | 11 +++++++---- ...test-child-process-fork-stdio-string-variant.js | 5 ++++- test/parallel/test-child-process-ipc-next-tick.js | 4 ++-- test/parallel/test-debugger-pid.js | 4 +++- ...newprotomethod-remove-unnecessary-prototypes.js | 7 ++++--- .../test-events-uncaught-exception-stack.js | 4 ++-- test/parallel/test-fs-buffertype-writesync.js | 7 ++++--- .../test-fs-cp-sync-verbatim-symlinks-invalid.mjs | 14 +++++++------- test/parallel/test-fs-readlink-type-check.js | 5 +++-- test/parallel/test-fs-rmdir-type-check.js | 5 +++-- test/parallel/test-fs-unlink-type-check.js | 5 +++-- test/parallel/test-http-correct-hostname.js | 4 ++-- test/parallel/test-http-hostname-typechecking.js | 5 +++-- .../test-http-req-close-robust-from-tampering.js | 3 ++- test/parallel/test-http-server-unconsume.js | 5 +++-- .../test-http2-server-settimeout-no-callback.js | 5 +++-- test/parallel/test-http2-status-code-invalid.js | 5 +++-- 17 files changed, 58 insertions(+), 40 deletions(-) diff --git a/test/parallel/test-btoa-atob.js b/test/parallel/test-btoa-atob.js index a2c8d9e3134c..3fde039f395e 100644 --- a/test/parallel/test-btoa-atob.js +++ b/test/parallel/test-btoa-atob.js @@ -26,14 +26,17 @@ assert.strictEqual(atob({ toString: () => '' }), ''); assert.strictEqual(atob({ [Symbol.toPrimitive]: () => '' }), ''); assert.throws(() => atob(Symbol()), /TypeError/); -[ +const testCases = [ undefined, false, () => {}, {}, [1], 0, 1, 0n, 1n, -Infinity, 'a', 'a\n\n\n', '\ra\r\r', ' a ', '\t\t\ta', 'a\f\f\f', '\ta\r \n\f', -].forEach((value) => - // See #2 - https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob +]; + +// See #2 - https://html.spec.whatwg.org/multipage/webappapis.html#dom-atob +for (const value of testCases) { assert.throws(() => atob(value), { constructor: DOMException, name: 'InvalidCharacterError', code: 5, - })); + }); +} diff --git a/test/parallel/test-child-process-fork-stdio-string-variant.js b/test/parallel/test-child-process-fork-stdio-string-variant.js index 6a396b51d9bd..91691b353a15 100644 --- a/test/parallel/test-child-process-fork-stdio-string-variant.js +++ b/test/parallel/test-child-process-fork-stdio-string-variant.js @@ -29,4 +29,7 @@ function test(stringVariant) { child.on('exit', common.mustCall((code) => assert.strictEqual(code, 0))); } -['pipe', 'inherit', 'ignore'].forEach(test); +const testCases = ['pipe', 'inherit', 'ignore']; +for (const value of testCases) { + test(value); +} diff --git a/test/parallel/test-child-process-ipc-next-tick.js b/test/parallel/test-child-process-ipc-next-tick.js index b23aefc85d11..849a927e251e 100644 --- a/test/parallel/test-child-process-ipc-next-tick.js +++ b/test/parallel/test-child-process-ipc-next-tick.js @@ -32,8 +32,8 @@ if (process.argv[2] === 'child') { child.on('message', common.mustCall((msg) => { assert.strictEqual(msg, 'ready'); - values.forEach((value) => { + for (const value of values) { child.send(value); - }); + }; })); } diff --git a/test/parallel/test-debugger-pid.js b/test/parallel/test-debugger-pid.js index 157939c05c73..6fcdac4d9d1d 100644 --- a/test/parallel/test-debugger-pid.js +++ b/test/parallel/test-debugger-pid.js @@ -18,7 +18,9 @@ interfacer.stderr.setEncoding('utf-8'); const onData = (data) => { data = (buffer + data).split('\n'); buffer = data.pop(); - data.forEach((line) => interfacer.emit('line', line)); + for (const line of data) { + interfacer.emit('line', line); + } }; interfacer.stdout.on('data', onData); interfacer.stderr.on('data', onData); diff --git a/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js b/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js index 22c0c8665d14..638c2c3c8722 100644 --- a/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js +++ b/test/parallel/test-env-newprotomethod-remove-unnecessary-prototypes.js @@ -7,13 +7,14 @@ require('../common'); const assert = require('assert'); const { internalBinding } = require('internal/test/binding'); -[ +const testCases = [ internalBinding('udp_wrap').UDP.prototype.bind6, internalBinding('tcp_wrap').TCP.prototype.bind6, internalBinding('udp_wrap').UDP.prototype.send6, internalBinding('tcp_wrap').TCP.prototype.bind, internalBinding('udp_wrap').UDP.prototype.close, internalBinding('tcp_wrap').TCP.prototype.open, -].forEach((binding, i) => { +]; +for (const [i, binding] of testCases.entries()) { assert.strictEqual('prototype' in binding, false, `Test ${i} failed`); -}); +} diff --git a/test/parallel/test-events-uncaught-exception-stack.js b/test/parallel/test-events-uncaught-exception-stack.js index 25fe9d6585f1..c11fcbabcb35 100644 --- a/test/parallel/test-events-uncaught-exception-stack.js +++ b/test/parallel/test-events-uncaught-exception-stack.js @@ -8,9 +8,9 @@ const EventEmitter = require('events'); process.on('uncaughtException', common.mustCall((err) => { const [firstLine, ...lines] = err.stack.split('\n'); assert.strictEqual(firstLine, 'Error'); - lines.forEach((line) => { + for (const line of lines) { assert.match(line, /^ {4}at/); - }); + } })); new EventEmitter().emit('error', new Error()); diff --git a/test/parallel/test-fs-buffertype-writesync.js b/test/parallel/test-fs-buffertype-writesync.js index 5649a00569a2..d1738dd3cc35 100644 --- a/test/parallel/test-fs-buffertype-writesync.js +++ b/test/parallel/test-fs-buffertype-writesync.js @@ -6,11 +6,12 @@ require('../common'); const assert = require('assert'); const fs = require('fs'); -[ +const testCases = [ true, false, 0, 1, Infinity, () => {}, {}, [], undefined, null, -].forEach((value) => { +]; +for (const value of testCases) { assert.throws( () => fs.writeSync(1, value), { message: /"buffer"/, code: 'ERR_INVALID_ARG_TYPE' } ); -}); +} diff --git a/test/parallel/test-fs-cp-sync-verbatim-symlinks-invalid.mjs b/test/parallel/test-fs-cp-sync-verbatim-symlinks-invalid.mjs index 3db176487f71..c9ec4e82f414 100644 --- a/test/parallel/test-fs-cp-sync-verbatim-symlinks-invalid.mjs +++ b/test/parallel/test-fs-cp-sync-verbatim-symlinks-invalid.mjs @@ -8,10 +8,10 @@ import fixtures from '../common/fixtures.js'; tmpdir.refresh(); const src = fixtures.path('copy/kitchen-sink'); -[1, [], {}, null, 1n, undefined, null, Symbol(), '', () => {}] - .forEach((verbatimSymlinks) => { - assert.throws( - () => cpSync(src, src, { verbatimSymlinks }), - { code: 'ERR_INVALID_ARG_TYPE' } - ); - }); +const testCases = [1, [], {}, null, 1n, undefined, null, Symbol(), '', () => {}]; +for (const verbatimSymlinks of testCases) { + assert.throws( + () => cpSync(src, src, { verbatimSymlinks }), + { code: 'ERR_INVALID_ARG_TYPE' } + ); +} diff --git a/test/parallel/test-fs-readlink-type-check.js b/test/parallel/test-fs-readlink-type-check.js index 58d431308c76..adf2c96126e7 100644 --- a/test/parallel/test-fs-readlink-type-check.js +++ b/test/parallel/test-fs-readlink-type-check.js @@ -4,7 +4,8 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); -[false, 1, {}, [], null, undefined].forEach((i) => { +const testCases = [false, 1, {}, [], null, undefined]; +for (const i of testCases) { assert.throws( () => fs.readlink(i, common.mustNotCall()), { @@ -19,4 +20,4 @@ const fs = require('fs'); name: 'TypeError' } ); -}); +} diff --git a/test/parallel/test-fs-rmdir-type-check.js b/test/parallel/test-fs-rmdir-type-check.js index 7014ce27f8e3..321386b0d7d1 100644 --- a/test/parallel/test-fs-rmdir-type-check.js +++ b/test/parallel/test-fs-rmdir-type-check.js @@ -4,7 +4,8 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); -[false, 1, [], {}, null, undefined].forEach((i) => { +const testCases = [false, 1, [], {}, null, undefined]; +for (const i of testCases) { assert.throws( () => fs.rmdir(i, common.mustNotCall()), { @@ -19,4 +20,4 @@ const fs = require('fs'); name: 'TypeError' } ); -}); +} diff --git a/test/parallel/test-fs-unlink-type-check.js b/test/parallel/test-fs-unlink-type-check.js index 006e9ad73485..62c1cf3da71b 100644 --- a/test/parallel/test-fs-unlink-type-check.js +++ b/test/parallel/test-fs-unlink-type-check.js @@ -4,7 +4,8 @@ const common = require('../common'); const assert = require('assert'); const fs = require('fs'); -[false, 1, {}, [], null, undefined].forEach((i) => { +const testCases = [false, 1, {}, [], null, undefined]; +for (const i of testCases) { assert.throws( () => fs.unlink(i, common.mustNotCall()), { @@ -19,4 +20,4 @@ const fs = require('fs'); name: 'TypeError' } ); -}); +} diff --git a/test/parallel/test-http-correct-hostname.js b/test/parallel/test-http-correct-hostname.js index c67a6d49f2e7..ea4b3cb25a09 100644 --- a/test/parallel/test-http-correct-hostname.js +++ b/test/parallel/test-http-correct-hostname.js @@ -15,7 +15,7 @@ if (common.hasCrypto) { modules.https = https; } -Object.keys(modules).forEach((module) => { +for (const module of Object.keys(modules)) { const doNotCall = common.mustNotCall( `${module}.request should not connect to ${module}://example.com%60x.example.com` ); @@ -25,4 +25,4 @@ Object.keys(modules).forEach((module) => { 'example.com`x.example.com', ]); req.abort(); -}); +}; diff --git a/test/parallel/test-http-hostname-typechecking.js b/test/parallel/test-http-hostname-typechecking.js index 368766e08701..c143106b115e 100644 --- a/test/parallel/test-http-hostname-typechecking.js +++ b/test/parallel/test-http-hostname-typechecking.js @@ -8,7 +8,8 @@ const http = require('http'); // when passed as the value of either options.hostname or options.host const vals = [{}, [], NaN, Infinity, -Infinity, true, false, 1, 0, new Date()]; -vals.forEach((v) => { + +for (const v of vals) { const received = common.invalidArgTypeHelper(v); assert.throws( () => http.request({ hostname: v }), @@ -31,7 +32,7 @@ vals.forEach((v) => { received } ); -}); +} // These values are OK and should not throw synchronously. // Only testing for 'hostname' validation so ignore connection errors. diff --git a/test/parallel/test-http-req-close-robust-from-tampering.js b/test/parallel/test-http-req-close-robust-from-tampering.js index edfdb309a7e4..75f57ad54133 100644 --- a/test/parallel/test-http-req-close-robust-from-tampering.js +++ b/test/parallel/test-http-req-close-robust-from-tampering.js @@ -7,7 +7,8 @@ const { connect } = require('net'); // cause an error. const server = createServer(common.mustCall((req, res) => { - req.client._events.close.forEach((fn) => { fn.bind(req)(); }); + const closeHandlers = req.client._events.close; + for (const fn of closeHandlers) { fn.bind(req)(); } })); server.unref(); diff --git a/test/parallel/test-http-server-unconsume.js b/test/parallel/test-http-server-unconsume.js index 0a0b5913812a..e92d7c127504 100644 --- a/test/parallel/test-http-server-unconsume.js +++ b/test/parallel/test-http-server-unconsume.js @@ -4,7 +4,8 @@ const assert = require('assert'); const http = require('http'); const net = require('net'); -['on', 'addListener', 'prependListener'].forEach((testFn) => { +const testCases = ['on', 'addListener', 'prependListener']; +for (const testFn of testCases) { let received = ''; const server = http.createServer(function(req, res) { @@ -30,4 +31,4 @@ const net = require('net'); })); })); })); -}); +}; diff --git a/test/parallel/test-http2-server-settimeout-no-callback.js b/test/parallel/test-http2-server-settimeout-no-callback.js index d0352067b7bd..a5cb080609f5 100644 --- a/test/parallel/test-http2-server-settimeout-no-callback.js +++ b/test/parallel/test-http2-server-settimeout-no-callback.js @@ -11,7 +11,8 @@ const http2 = require('http2'); const verifyCallbacks = common.mustCall((server) => { const testTimeout = 10; - [true, 1, {}, [], null, 'test'].forEach((notFunction) => { + const testCases = [true, 1, {}, [], null, 'test']; + for (const notFunction of testCases) { assert.throws( () => server.setTimeout(testTimeout, notFunction), { @@ -19,7 +20,7 @@ const verifyCallbacks = common.mustCall((server) => { code: 'ERR_INVALID_ARG_TYPE', } ); - }); + }; // No callback const returnedVal = server.setTimeout(testTimeout); diff --git a/test/parallel/test-http2-status-code-invalid.js b/test/parallel/test-http2-status-code-invalid.js index a906c706d7d7..a8b92aad6369 100644 --- a/test/parallel/test-http2-status-code-invalid.js +++ b/test/parallel/test-http2-status-code-invalid.js @@ -19,9 +19,10 @@ function expectsError(code) { server.on('stream', common.mustCall((stream) => { // Anything lower than 100 and greater than 599 is rejected - [ 99, 700, 1000 ].forEach((i) => { + const testCases = [ 99, 700, 1000 ]; + for (const i of testCases) { assert.throws(() => stream.respond({ ':status': i }), expectsError(i)); - }); + } stream.respond(); stream.end(); From d099639740a2269131fd1ec9cb211c1286822885 Mon Sep 17 00:00:00 2001 From: freida-code <150387862+freida-code@users.noreply.github.com> Date: Thu, 13 Aug 2026 15:53:37 -0400 Subject: [PATCH 3/9] test: convert test-async-local-storage-bind to async loop Signed-off-by: freida-code <150387862+freida-code@users.noreply.github.com> PR-URL: https://github.com/nodejs/node/pull/65270 Reviewed-By: James M Snell Reviewed-By: Aviv Keller Reviewed-By: Ethan Arrowood --- test/parallel/test-async-local-storage-bind.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/parallel/test-async-local-storage-bind.js b/test/parallel/test-async-local-storage-bind.js index d8d4c4599826..01aa449c1d46 100644 --- a/test/parallel/test-async-local-storage-bind.js +++ b/test/parallel/test-async-local-storage-bind.js @@ -4,11 +4,11 @@ const common = require('../common'); const assert = require('assert'); const { AsyncLocalStorage } = require('async_hooks'); -[1, false, '', {}, []].forEach((i) => { +for (const i of [1, false, '', {}, []]) { assert.throws(() => AsyncLocalStorage.bind(i), { code: 'ERR_INVALID_ARG_TYPE' }); -}); +} const fn = common.mustCall(AsyncLocalStorage.bind(() => 123)); assert.strictEqual(fn(), 123); From 04a0c270bea9903d823fdc21c6ae3b0ccbe302fa Mon Sep 17 00:00:00 2001 From: "Node.js GitHub Bot" Date: Sun, 16 Aug 2026 04:43:26 -0400 Subject: [PATCH 4/9] tools: update nixpkgs-unstable to 6b5e5b7a6631f065bf6908986990b37d845 PR-URL: https://github.com/nodejs/node/pull/65224 Reviewed-By: Filip Skokan Reviewed-By: Colin Ihrig Reviewed-By: Antoine du Hamel --- tools/nix/openssl-matrix.nix | 3 +-- tools/nix/pkgs-26.05.nix | 4 ++-- tools/nix/pkgs.nix | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/nix/openssl-matrix.nix b/tools/nix/openssl-matrix.nix index 56cc7d506ad6..66cfb129c432 100644 --- a/tools/nix/openssl-matrix.nix +++ b/tools/nix/openssl-matrix.nix @@ -1,6 +1,6 @@ { pkgs ? import ./pkgs.nix { - config.permittedInsecurePackages = [ "openssl-1.1.1w" ]; + config.permittedInsecurePackages = [ ]; }, }: @@ -11,7 +11,6 @@ # Other OpenSSL variants we want to test for: inherit (pkgs) boringssl - openssl_1_1 openssl_3 openssl_3_6 openssl_4_0 diff --git a/tools/nix/pkgs-26.05.nix b/tools/nix/pkgs-26.05.nix index 7a1167a798d1..daa955f8a6c4 100644 --- a/tools/nix/pkgs-26.05.nix +++ b/tools/nix/pkgs-26.05.nix @@ -1,10 +1,10 @@ arg: let repo = "https://github.com/NixOS/nixpkgs"; - rev = "329c3d2af6d1b618705150ea39f72c15eb4e613e"; + rev = "e0c84f9d0ad137f076dc957494f5b39885597d4f"; nixpkgs = import (builtins.fetchTarball { url = "${repo}/archive/${rev}.tar.gz"; - sha256 = "0hkr1j8mm50gpxd55y85vq85bxxww8rhwf6mkvkrg0qw21dmvlmd"; + sha256 = "0mp3pbx4mznxf55mmr5nbrac1r9i38b0dyqpynxiqwcpfhz4kfrq"; }) arg; in # Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel diff --git a/tools/nix/pkgs.nix b/tools/nix/pkgs.nix index 9b999f68c29c..54ebabcf16c6 100644 --- a/tools/nix/pkgs.nix +++ b/tools/nix/pkgs.nix @@ -1,10 +1,10 @@ arg: let repo = "https://github.com/NixOS/nixpkgs"; - rev = "bcdf747749ad31ab043d6341a18699a8b9b62ef0"; + rev = "6b5e5b7a6631f065bf6908986990b37d845f847f"; nixpkgs = import (builtins.fetchTarball { url = "${repo}/archive/${rev}.tar.gz"; - sha256 = "10vv47y0b3k3aq2l52rqd5qzk50a7jbdcamd8rwc0g02mm6blxn8"; + sha256 = "0vi99516bn335vdzcjmvrkff8ikj0brpmjfcfdrjnb8bfd0wlr5j"; }) arg; in # Unstable channel no longer supports Intel architecture for macOS. We can use the 26.05 channel From 46cac5a7c2f0e7c5b3a08f36173f0e42a39f765f Mon Sep 17 00:00:00 2001 From: Lazizbek Ergashev Date: Sun, 16 Aug 2026 14:40:37 +0500 Subject: [PATCH 5/9] doc: add missing `added:` tags to `fs.lchmod` Signed-off-by: Lazizbek Ergashev PR-URL: https://github.com/nodejs/node/pull/65283 Fixes: https://github.com/nodejs/node/issues/65280 Refs: https://github.com/nodejs/node-v0.x-archive/issues/853 Refs: https://github.com/nodejs/node/commit/3935adced09cd557a836d00558b52d777b9a20a2 Refs: https://github.com/nodejs/node/pull/18297 Reviewed-By: Antoine du Hamel Reviewed-By: James M Snell --- doc/api/fs.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/api/fs.md b/doc/api/fs.md index 21eaa6af0e1c..f95b1d85abec 100644 --- a/doc/api/fs.md +++ b/doc/api/fs.md @@ -1478,6 +1478,7 @@ const { glob } = require('node:fs/promises'); ### `fsPromises.lchmod(path, mode)` @@ -3666,7 +3667,8 @@ glob('**/*.js', (err, matches) => { ### `fs.lchmod(path, mode, callback)` > Stability: 0 - Deprecated From ad7a5b8302ae54b6e6dc77e03eabc5a3218dfb85 Mon Sep 17 00:00:00 2001 From: Stewart X Addison <6487691+sxa@users.noreply.github.com> Date: Sun, 16 Aug 2026 10:40:47 +0100 Subject: [PATCH 6/9] build: update binary-upload to use correct tarball name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the binary-upload target uses $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz as the name to upload whereas it is created by the $(BINARYTAR) target as $(BINARYNAME). Since BINARYNAME includes the optional VARIATION when present this gets missed out int he binary-upload target, for example during a release build for Alpine/musl. This commit changes the binary-upload target to use the same variable for the tarball that is used when the file is created. Signed-off-by: Stewart X Addison PR-URL: https://github.com/nodejs/node/pull/65282 Reviewed-By: Richard Lau Reviewed-By: Luigi Pinca Reviewed-By: Gürgün Dayıoğlu --- Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index bc9dd7a144db..10292db04e8c 100644 --- a/Makefile +++ b/Makefile @@ -1449,15 +1449,15 @@ binary: $(BINARYTAR) ## Build release binary tarballs. # Note: this is strictly for release builds on release machines only. binary-upload: binary ssh $(STAGINGSERVER) "mkdir -p nodejs/$(DISTTYPEDIR)/$(FULLVERSION)" - chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz - scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz - ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz" - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.gz.done" + chmod 664 $(BINARYNAME).tar.gz + scp -p $(BINARYNAME).tar.gz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz" + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.gz.done" ifeq ($(XZ), 1) - chmod 664 $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz - scp -p $(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz - ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz" - ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(TARNAME)-$(OSTYPE)-$(ARCH).tar.xz.done" + chmod 664 $(BINARYNAME).tar.xz + scp -p $(BINARYNAME).tar.xz $(STAGINGSERVER):nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz + ssh $(STAGINGSERVER) "rclone copyto nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz $(CLOUDFLARE_BUCKET)/nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz" + ssh $(STAGINGSERVER) "touch nodejs/$(DISTTYPEDIR)/$(FULLVERSION)/$(BINARYNAME).tar.xz.done" endif .PHONY: bench-all From 9129555dc2d9f32339e648e280975f3768a8046c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=84=9C=EC=9A=B8=EB=AF=BC=ED=8A=B8=EC=B4=88=EC=BD=94?= Date: Mon, 17 Aug 2026 10:59:52 +0900 Subject: [PATCH 7/9] doc: fix typo in onboarding.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 서울민트초코 PR-URL: https://github.com/nodejs/node/pull/65295 Reviewed-By: Aviv Keller Reviewed-By: Colin Ihrig Reviewed-By: Luigi Pinca --- onboarding.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onboarding.md b/onboarding.md index bc690190b490..74c114526044 100644 --- a/onboarding.md +++ b/onboarding.md @@ -283,8 +283,8 @@ needs to be pointed out separately during the onboarding. including accommodations, transportation, and visa fees (even in case the visa is denied) if needed. Check out the [summit](https://github.com/nodejs/summit) repository for details. -* If you are interested in helping to fix coverity reports consider requesting - access to the projects coverity project as outlined in [static-analysis][]. +* If you are interested in helping to fix coverity reports, consider requesting + access to the project's coverity project as outlined in [static-analysis][]. * If you are interested in helping out with CI reliability, check out the [reliability repository][] and [guide on how to deal with CI flakes][]. When fixing a flaky test, it is recommended to run [`node-stress-single-test`][] From 6054ff3a9499fe80b91502d6be32ed4ce7e5f703 Mon Sep 17 00:00:00 2001 From: greenhead Date: Mon, 17 Aug 2026 11:00:04 +0900 Subject: [PATCH 8/9] doc: fix lint clean command Signed-off-by: greenhead PR-URL: https://github.com/nodejs/node/pull/65274 Refs: https://github.com/nodejs/node/pull/55266 Reviewed-By: Luigi Pinca Reviewed-By: Daeyeon Jeong --- doc/contributing/using-internal-errors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/contributing/using-internal-errors.md b/doc/contributing/using-internal-errors.md index db63abfe28a4..fec768663631 100644 --- a/doc/contributing/using-internal-errors.md +++ b/doc/contributing/using-internal-errors.md @@ -84,7 +84,7 @@ give users a place to go to easily look up the meaning of individual error codes. In case `make lint` fails to detect the new error codes added into `errors.md`, -the markdown linting cache must be cleaned with `make lint-md-clean`. +the markdown linting cache must be cleaned with `make lint-clean`. ## Testing new errors From 26398a94c1d934bb9068ca2d905f14a9f83c8a1d Mon Sep 17 00:00:00 2001 From: greenhead Date: Mon, 17 Aug 2026 11:00:16 +0900 Subject: [PATCH 9/9] stream: use validateNumber for BYOB reader options.min The error thrown for a non-number min is unchanged. Signed-off-by: greenhead PR-URL: https://github.com/nodejs/node/pull/65014 Reviewed-By: Daeyeon Jeong --- lib/internal/webstreams/readablestream.js | 4 +- ...est-whatwg-readablestream-byob-read-min.js | 41 +++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 test/parallel/test-whatwg-readablestream-byob-read-min.js diff --git a/lib/internal/webstreams/readablestream.js b/lib/internal/webstreams/readablestream.js index 1a9287bc817e..84f16dc7b4a1 100644 --- a/lib/internal/webstreams/readablestream.js +++ b/lib/internal/webstreams/readablestream.js @@ -62,6 +62,7 @@ const { const { validateAbortSignal, validateBuffer, + validateNumber, validateObject, kValidateObjectAllowObjects, kValidateObjectAllowObjectsAndNull, @@ -1086,8 +1087,7 @@ class ReadableStreamBYOBReader { // detached, but there's no API available to use to check that. const min = options?.min ?? 1; - if (typeof min !== 'number') - throw new ERR_INVALID_ARG_TYPE('options.min', 'number', min); + validateNumber(min, 'options.min'); if (!NumberIsInteger(min)) throw new ERR_INVALID_ARG_VALUE('options.min', min, 'must be an integer'); if (min <= 0) diff --git a/test/parallel/test-whatwg-readablestream-byob-read-min.js b/test/parallel/test-whatwg-readablestream-byob-read-min.js new file mode 100644 index 000000000000..c428caa83478 --- /dev/null +++ b/test/parallel/test-whatwg-readablestream-byob-read-min.js @@ -0,0 +1,41 @@ +'use strict'; +const common = require('../common'); +const assert = require('node:assert'); + +const { + ReadableStream, +} = require('node:stream/web'); + +// Validation of the options.min argument of ReadableStreamBYOBReader.read() +// must reject with the same errors regardless of how the checks are implemented internally. + +const reader = new ReadableStream({ type: 'bytes' }) + .getReader({ mode: 'byob' }); + +(async () => { + // A null min is not covered here: `options?.min ?? 1` turns it into + // the default before validation, so it never reaches the type check. + for (const min of ['1', true, {}, [], 1n]) { + await assert.rejects( + reader.read(new Uint8Array(8), { min }), + { code: 'ERR_INVALID_ARG_TYPE' }, + ); + } + + for (const min of [NaN, 1.5, 0, -1]) { + await assert.rejects( + reader.read(new Uint8Array(8), { min }), + { code: 'ERR_INVALID_ARG_VALUE' }, + ); + } + + await assert.rejects( + reader.read(new Uint8Array(8), { min: 9 }), + { code: 'ERR_OUT_OF_RANGE' }, + ); + + await assert.rejects( + reader.read(new DataView(new ArrayBuffer(8)), { min: 9 }), + { code: 'ERR_OUT_OF_RANGE' }, + ); +})().then(common.mustCall());