From 5b26195c696660df0ab3ad8bf767d5ed492f434a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Sat, 7 Feb 2026 13:58:30 +0200 Subject: [PATCH 1/2] fix(module-runner): prevent crash on negative column in stacktrace --- packages/vite/src/module-runner/sourcemap/interceptor.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/vite/src/module-runner/sourcemap/interceptor.ts b/packages/vite/src/module-runner/sourcemap/interceptor.ts index 8173158e97ad81..49b109615ac8aa 100644 --- a/packages/vite/src/module-runner/sourcemap/interceptor.ts +++ b/packages/vite/src/module-runner/sourcemap/interceptor.ts @@ -358,8 +358,8 @@ function wrapCallSite(frame: CallSite, state: State) { // from getScriptNameOrSourceURL() instead const source = frame.getFileName() || frame.getScriptNameOrSourceURL() if (source) { - const line = frame.getLineNumber() as number - const column = (frame.getColumnNumber() as number) - 1 + const line = frame.getLineNumber() ?? 0 + const column = (frame.getColumnNumber() ?? 1) - 1 const position = mapSourcePosition({ name: null, From b62a076fe6493e60e6785bf53668ec456d44c62a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ari=20Perkki=C3=B6?= Date: Sat, 7 Feb 2026 22:31:18 +0200 Subject: [PATCH 2/2] test: failing test for negative column in stacktrace --- .../__tests__/server-source-maps.spec.ts | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts b/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts index d3d7a3ffc925d8..6caeea61be17b1 100644 --- a/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts +++ b/packages/vite/src/node/ssr/runtime/__tests__/server-source-maps.spec.ts @@ -1,5 +1,9 @@ +import { runInThisContext } from 'node:vm' +import { resolve } from 'node:path' import { describe, expect } from 'vitest' import type { ViteDevServer } from '../../..' +import type { ModuleRunnerContext } from '../../../../module-runner' +import { ESModulesEvaluator } from '../../../../module-runner' import { createFixtureEditor, createModuleRunnerTester, @@ -135,3 +139,39 @@ describe('module runner initialization', async () => { `) }) }) + +describe('module runner with node:vm executor', async () => { + class Evaluator extends ESModulesEvaluator { + async runInlinedModule(_: ModuleRunnerContext, __: string) { + // Mimics VitestModuleEvaluator + const initModule = runInThisContext( + '() => { throw new Error("example")}', + { + lineOffset: 0, + columnOffset: -100, + filename: resolve(import.meta.dirname, 'fixtures/a.ts'), + }, + ) + + initModule() + } + } + + const it = await createModuleRunnerTester( + {}, + { + sourcemapInterceptor: 'prepareStackTrace', + evaluator: new Evaluator(), + }, + ) + + it('should not crash when error stacktrace contains negative column', async ({ + runner, + }) => { + const error = await runner.import('/fixtures/a.ts').catch((err) => err) + + expect(() => + error.stack.includes('.stack access triggers the bug'), + ).not.toThrow() + }) +})