From 6a0b05f4286a2b639901d5edbcaf7ceb0e7a1141 Mon Sep 17 00:00:00 2001 From: June Kim Date: Tue, 26 May 2026 16:45:59 -0700 Subject: [PATCH 1/2] lib: fix ERR_INVALID_ARG_TYPE with --enable-source-maps Signed-off-by: June Kim --- lib/internal/errors/error_source.js | 11 +++++- .../source-map/assert-no-source-map.cjs | 15 ++++++++ .../source-map/assert-no-source-map.mjs | 16 ++++++++ test/parallel/test-assert-ok-source-maps.js | 38 +++++++++++++++++++ 4 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/source-map/assert-no-source-map.cjs create mode 100644 test/fixtures/source-map/assert-no-source-map.mjs create mode 100644 test/parallel/test-assert-ok-source-maps.js diff --git a/lib/internal/errors/error_source.js b/lib/internal/errors/error_source.js index eddd6af230801b..c17f5a151c7014 100644 --- a/lib/internal/errors/error_source.js +++ b/lib/internal/errors/error_source.js @@ -32,6 +32,10 @@ function getErrorSourceLocation(error) { startColumn, } = pos; + if (!sourceLine) { + return; + } + // Source map is not enabled. Return the source line directly. if (!getSourceMapsSupport().enabled) { return { sourceLine, startColumn }; @@ -39,7 +43,8 @@ function getErrorSourceLocation(error) { const sm = findSourceMap(scriptResourceName); if (sm === undefined) { - return; + // No source map for this file; use the generated source line. + return { sourceLine, startColumn }; } const { originalLine, @@ -49,7 +54,9 @@ function getErrorSourceLocation(error) { const originalSourceLine = getSourceLine(sm, originalSource, originalLine, originalColumn); if (!originalSourceLine) { - return; + // Source map exists but original source is unavailable; use the + // generated source line rather than returning undefined. + return { sourceLine, startColumn }; } return { diff --git a/test/fixtures/source-map/assert-no-source-map.cjs b/test/fixtures/source-map/assert-no-source-map.cjs new file mode 100644 index 00000000000000..09629af3056441 --- /dev/null +++ b/test/fixtures/source-map/assert-no-source-map.cjs @@ -0,0 +1,15 @@ +'use strict'; + +// Fixture for test/parallel/test-assert-ok-source-maps.js (CommonJS variant). +// See assert-no-source-map.mjs for the rationale (issue #63169). +const assert = require('node:assert'); + +try { + assert.ok(false); +} catch (e) { + process.stdout.write(e.constructor.name + '\n'); + process.stdout.write(e.code + '\n'); + process.stdout.write(e.message + '\n'); + process.exit(0); +} +process.exit(1); diff --git a/test/fixtures/source-map/assert-no-source-map.mjs b/test/fixtures/source-map/assert-no-source-map.mjs new file mode 100644 index 00000000000000..faeb6031a5ba13 --- /dev/null +++ b/test/fixtures/source-map/assert-no-source-map.mjs @@ -0,0 +1,16 @@ +// Fixture for test/parallel/test-assert-ok-source-maps.js. +// Run with --enable-source-maps; the file has no source map, so the error's +// source line resolution must fall back to the generated line instead of +// throwing ERR_INVALID_ARG_TYPE (regression test for +// https://github.com/nodejs/node/issues/63169). +import { strict as assert } from 'node:assert'; + +try { + assert(false); +} catch (e) { + process.stdout.write(e.constructor.name + '\n'); + process.stdout.write(e.code + '\n'); + process.stdout.write(e.message + '\n'); + process.exit(0); +} +process.exit(1); diff --git a/test/parallel/test-assert-ok-source-maps.js b/test/parallel/test-assert-ok-source-maps.js new file mode 100644 index 00000000000000..71e6860664fda6 --- /dev/null +++ b/test/parallel/test-assert-ok-source-maps.js @@ -0,0 +1,38 @@ +'use strict'; + +// Regression test for https://github.com/nodejs/node/issues/63169 +// When --enable-source-maps is enabled but the script has no source map, +// assert(false) should throw AssertionError, not TypeError ERR_INVALID_ARG_TYPE. + +require('../common'); +const assert = require('node:assert'); +const { spawnSync } = require('node:child_process'); +const { test } = require('node:test'); +const fixtures = require('../common/fixtures'); + +function runWithSourceMaps(fixture) { + return spawnSync(process.execPath, [ + '--enable-source-maps', + fixtures.path('source-map', fixture), + ]); +} + +test('assert(false) in .mjs with --enable-source-maps throws AssertionError', () => { + const result = runWithSourceMaps('assert-no-source-map.mjs'); + + assert.strictEqual(result.status, 0, `process exited with ${result.status}: ${result.stderr}`); + const lines = result.stdout.toString().trim().split('\n'); + assert.strictEqual(lines[0], 'AssertionError'); + assert.strictEqual(lines[1], 'ERR_ASSERTION'); + assert.match(lines[2], /assert\(false\)/); +}); + +test('assert.ok(false) in .cjs with --enable-source-maps throws AssertionError', () => { + const result = runWithSourceMaps('assert-no-source-map.cjs'); + + assert.strictEqual(result.status, 0, `process exited with ${result.status}: ${result.stderr}`); + const lines = result.stdout.toString().trim().split('\n'); + assert.strictEqual(lines[0], 'AssertionError'); + assert.strictEqual(lines[1], 'ERR_ASSERTION'); + assert.match(lines[2], /assert\.ok\(false\)/); +}); From 9a7f346fcd7142a7c97f3634db45c59b9d2d6df2 Mon Sep 17 00:00:00 2001 From: June Kim Date: Fri, 26 Jun 2026 20:26:42 -0400 Subject: [PATCH 2/2] test: move source-map assert regression into output snapshots Fold the .mjs and .cjs --enable-source-maps cases from the standalone test-assert-ok-source-maps.js into the existing snapshot output test, following the setup in test-node-output-sourcemaps.mjs as requested in review. The fixtures live under test/fixtures/source-map/output/ with a `// Flags: --enable-source-maps` directive and assert AssertionError output via snapshots instead of bespoke spawnSync assertions. Refs: https://github.com/nodejs/node/issues/63169 Signed-off-by: June Kim --- .../source-map/assert-no-source-map.cjs | 15 -------- .../source-map/assert-no-source-map.mjs | 16 -------- .../source_map_assert_no_source_map.mjs | 9 +++++ .../source_map_assert_no_source_map.snapshot | 20 ++++++++++ .../source_map_assert_ok_no_source_map.cjs | 10 +++++ ...ource_map_assert_ok_no_source_map.snapshot | 20 ++++++++++ test/parallel/test-assert-ok-source-maps.js | 38 ------------------- test/parallel/test-node-output-sourcemaps.mjs | 2 + 8 files changed, 61 insertions(+), 69 deletions(-) delete mode 100644 test/fixtures/source-map/assert-no-source-map.cjs delete mode 100644 test/fixtures/source-map/assert-no-source-map.mjs create mode 100644 test/fixtures/source-map/output/source_map_assert_no_source_map.mjs create mode 100644 test/fixtures/source-map/output/source_map_assert_no_source_map.snapshot create mode 100644 test/fixtures/source-map/output/source_map_assert_ok_no_source_map.cjs create mode 100644 test/fixtures/source-map/output/source_map_assert_ok_no_source_map.snapshot delete mode 100644 test/parallel/test-assert-ok-source-maps.js diff --git a/test/fixtures/source-map/assert-no-source-map.cjs b/test/fixtures/source-map/assert-no-source-map.cjs deleted file mode 100644 index 09629af3056441..00000000000000 --- a/test/fixtures/source-map/assert-no-source-map.cjs +++ /dev/null @@ -1,15 +0,0 @@ -'use strict'; - -// Fixture for test/parallel/test-assert-ok-source-maps.js (CommonJS variant). -// See assert-no-source-map.mjs for the rationale (issue #63169). -const assert = require('node:assert'); - -try { - assert.ok(false); -} catch (e) { - process.stdout.write(e.constructor.name + '\n'); - process.stdout.write(e.code + '\n'); - process.stdout.write(e.message + '\n'); - process.exit(0); -} -process.exit(1); diff --git a/test/fixtures/source-map/assert-no-source-map.mjs b/test/fixtures/source-map/assert-no-source-map.mjs deleted file mode 100644 index faeb6031a5ba13..00000000000000 --- a/test/fixtures/source-map/assert-no-source-map.mjs +++ /dev/null @@ -1,16 +0,0 @@ -// Fixture for test/parallel/test-assert-ok-source-maps.js. -// Run with --enable-source-maps; the file has no source map, so the error's -// source line resolution must fall back to the generated line instead of -// throwing ERR_INVALID_ARG_TYPE (regression test for -// https://github.com/nodejs/node/issues/63169). -import { strict as assert } from 'node:assert'; - -try { - assert(false); -} catch (e) { - process.stdout.write(e.constructor.name + '\n'); - process.stdout.write(e.code + '\n'); - process.stdout.write(e.message + '\n'); - process.exit(0); -} -process.exit(1); diff --git a/test/fixtures/source-map/output/source_map_assert_no_source_map.mjs b/test/fixtures/source-map/output/source_map_assert_no_source_map.mjs new file mode 100644 index 00000000000000..d6035109d56db8 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_assert_no_source_map.mjs @@ -0,0 +1,9 @@ +// Flags: --enable-source-maps + +import '../../../common/index.mjs'; +import { strict as assert } from 'node:assert'; + +// Regression test for https://github.com/nodejs/node/issues/63169 +// Under --enable-source-maps with no source map for this file, a failing +// assert(value) must throw AssertionError, not TypeError ERR_INVALID_ARG_TYPE. +assert(false); diff --git a/test/fixtures/source-map/output/source_map_assert_no_source_map.snapshot b/test/fixtures/source-map/output/source_map_assert_no_source_map.snapshot new file mode 100644 index 00000000000000..0a2ea1a45fe6f3 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_assert_no_source_map.snapshot @@ -0,0 +1,20 @@ +node:internal/modules/run_main: + triggerUncaughtException( + ^ + +AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value: + + assert(false) + + at file:///test/fixtures/source-map/output/source_map_assert_no_source_map.mjs:9:1 + at + at { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: '==', + diff: 'simple' +} + +Node.js diff --git a/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.cjs b/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.cjs new file mode 100644 index 00000000000000..21f2ec8965fb05 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.cjs @@ -0,0 +1,10 @@ +// Flags: --enable-source-maps + +'use strict'; +require('../../../common'); +const assert = require('node:assert'); + +// Regression test for https://github.com/nodejs/node/issues/63169 +// Under --enable-source-maps with no source map for this file, a failing +// assert.ok(value) must throw AssertionError, not TypeError ERR_INVALID_ARG_TYPE. +assert.ok(false); diff --git a/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.snapshot b/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.snapshot new file mode 100644 index 00000000000000..8ee5ff2ee29498 --- /dev/null +++ b/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.snapshot @@ -0,0 +1,20 @@ +node:internal/assert/utils: + throw error; + ^ + +AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value: + + assert.ok(false) + + at Object. (/test/fixtures/source-map/output/source_map_assert_ok_no_source_map.cjs:10:8) + at + at { + generatedMessage: true, + code: 'ERR_ASSERTION', + actual: false, + expected: true, + operator: '==', + diff: 'simple' +} + +Node.js diff --git a/test/parallel/test-assert-ok-source-maps.js b/test/parallel/test-assert-ok-source-maps.js deleted file mode 100644 index 71e6860664fda6..00000000000000 --- a/test/parallel/test-assert-ok-source-maps.js +++ /dev/null @@ -1,38 +0,0 @@ -'use strict'; - -// Regression test for https://github.com/nodejs/node/issues/63169 -// When --enable-source-maps is enabled but the script has no source map, -// assert(false) should throw AssertionError, not TypeError ERR_INVALID_ARG_TYPE. - -require('../common'); -const assert = require('node:assert'); -const { spawnSync } = require('node:child_process'); -const { test } = require('node:test'); -const fixtures = require('../common/fixtures'); - -function runWithSourceMaps(fixture) { - return spawnSync(process.execPath, [ - '--enable-source-maps', - fixtures.path('source-map', fixture), - ]); -} - -test('assert(false) in .mjs with --enable-source-maps throws AssertionError', () => { - const result = runWithSourceMaps('assert-no-source-map.mjs'); - - assert.strictEqual(result.status, 0, `process exited with ${result.status}: ${result.stderr}`); - const lines = result.stdout.toString().trim().split('\n'); - assert.strictEqual(lines[0], 'AssertionError'); - assert.strictEqual(lines[1], 'ERR_ASSERTION'); - assert.match(lines[2], /assert\(false\)/); -}); - -test('assert.ok(false) in .cjs with --enable-source-maps throws AssertionError', () => { - const result = runWithSourceMaps('assert-no-source-map.cjs'); - - assert.strictEqual(result.status, 0, `process exited with ${result.status}: ${result.stderr}`); - const lines = result.stdout.toString().trim().split('\n'); - assert.strictEqual(lines[0], 'AssertionError'); - assert.strictEqual(lines[1], 'ERR_ASSERTION'); - assert.match(lines[2], /assert\.ok\(false\)/); -}); diff --git a/test/parallel/test-node-output-sourcemaps.mjs b/test/parallel/test-node-output-sourcemaps.mjs index 26baa0cd53afed..c96eac2bd0310c 100644 --- a/test/parallel/test-node-output-sourcemaps.mjs +++ b/test/parallel/test-node-output-sourcemaps.mjs @@ -5,6 +5,8 @@ import { describe, it } from 'node:test'; describe('sourcemaps output', { concurrency: !process.env.TEST_PARALLEL }, () => { const tests = [ + { name: 'source-map/output/source_map_assert_no_source_map.mjs' }, + { name: 'source-map/output/source_map_assert_ok_no_source_map.cjs' }, { name: 'source-map/output/source_map_disabled_by_api.js' }, { name: 'source-map/output/source_map_disabled_by_process_api.js' }, { name: 'source-map/output/source_map_enabled_by_api.js' },