vitest-dev/vitest · error · Error
Cannot parse '${filename}' because "module.stripTypeScriptTy
Error message
Cannot parse '${filename}' because "module.stripTypeScriptTypes" is not supported. Module mocking requires Node.js 22.15 or higher. This is NOT a bug of Vitest. What it means
Vitest's mocker must statically enumerate a mocked module's exports, which for TypeScript sources requires stripping types via Node's `module.stripTypeScriptTypes` (added in Node 22.15). On an older Node runtime that API is `undefined`, so `transformCode` in parsers.ts refuses to guess and throws rather than silently producing a broken automock.
Source
Thrown at packages/mocker/src/node/parsers.ts:26
export async function initSyntaxLexers(): Promise<void> {
await Promise.all([
initCjsLexer(),
initModuleLexer,
])
}
const isTransform = process.execArgv.includes('--experimental-transform-types')
|| process.env.NODE_OPTIONS?.includes('--experimental-transform-types')
export function transformCode(code: string, filename: string): string {
const ext = extname(filename.split('?')[0])
const isTs = ext === '.ts' || ext === '.cts' || ext === '.mts'
if (!isTs) {
return code
}
if (!module.stripTypeScriptTypes) {
throw new Error(`Cannot parse '${filename}' because "module.stripTypeScriptTypes" is not supported. Module mocking requires Node.js 22.15 or higher. This is NOT a bug of Vitest.`)
}
return module.stripTypeScriptTypes(code, { mode: isTransform ? 'transform' : 'strip' })
}
const cachedFileExports = new Map<string, string[]>()
export function collectModuleExports(
filename: string,
code: string,
format: 'module' | 'commonjs',
exports: string[] = [],
): string[] {
if (format === 'module') {
const [imports_, exports_] = parseModuleSyntax(code, filename)
const fileExports = [...exports_.map(p => p.n)]
imports_.forEach(({ ss: start, se: end, n: name }) => {
const substring = code.substring(start, end).replace(/ +/g, ' ')
if (name && substring.startsWith('export *') && !substring.startsWith('export * as')) {View on GitHub (pinned to d568f8ce37)
Solutions
- Upgrade Node.js to 22.15 or newer (verify with `node -e "console.log(typeof require('module').stripTypeScriptTypes)"`).
- If you cannot upgrade, supply a full factory so Vitest skips export analysis: `vi.mock('./mod.ts', () => ({ default: stub }))`.
- Mock the compiled `.js`/`.mjs` output instead of the `.ts` source so type stripping is unnecessary.
Example fix
// before
vi.mock('./config.ts')
// after (Node < 22.15 workaround)
vi.mock('./config.ts', () => ({
default: { port: 3000, host: 'localhost' },
})) Defensive patterns
Strategy: validation
Validate before calling
import module from 'node:module'
const canStripTs = typeof module.stripTypeScriptTypes === 'function'
if (!canStripTs) {
console.warn(
`vi.mock of TypeScript modules needs Node >= 22.15; current is ${process.version}. ` +
`Provide an explicit factory or upgrade Node.`,
)
} Prevention
- Pin `engines.node` to `>=22.15` in package.json and enforce it in CI.
- When targeting Node < 22.15, always pass a full factory to `vi.mock` for TS modules.
- Add a smoke test that mocks one TS module so version regressions fail fast in CI.
When it happens
Trigger: Calling `vi.mock('./mod.ts')` (or letting Vitest automock a `.ts`/`.cts`/`.mts` dependency) while running on Node older than 22.15, where the `!module.stripTypeScriptTypes` guard at parsers.ts:25 is true.
Common situations: CI pinned to Node 20 LTS; local dev on Node 18/20; Docker base image lagging; upgrading Vitest without bumping the Node engines; monorepos whose root `engines.node` still allows v20.
Related errors
- Cannot automock '${url}' because it failed to parse.
- Cannot parse '${filename}' because "module.stripTypeScriptTy
- Cannot parse the module format of '${url}' because "module.f
- Cannot parse '${url}' because "module.stripTypeScriptTypes"
- toHaveFormValues must be called with an object of expected f
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/e6a486ab6dc7cd8d.json.
Report an issue: GitHub.