vitest-dev/vitest · error · Error
Cannot parse the module format of '${url}' because "module.f
Error message
Cannot parse the module format of '${url}' because "module.findPackageJSON" is not available. Upgrade to Node 22.14 to use this feature. This is NOT a bug of Vitest. What it means
To classify a `.js`/`.ts`/extensionless file as ESM or CJS, the mocker reads the nearest `package.json` `"type"` field through Node's `module.findPackageJSON` (added in Node 22.14). When that function is missing, the module format cannot be determined safely, so `resolveModuleFormat` throws instead of guessing wrong and producing an invalid mock.
Source
Thrown at packages/mocker/src/node/parsers.ts:138
return []
}
return Array.from(new Set(exports))
}
export function resolveModuleFormat(url: string, code: string): 'module' | 'commonjs' | undefined {
const ext = extname(url)
if (ext === '.cjs' || ext === '.cts') {
return 'commonjs'
}
else if (ext === '.mjs' || ext === '.mts') {
return 'module'
}
// https://nodejs.org/api/packages.html#syntax-detection
else if (ext === '.js' || ext === '.ts' || ext === '') {
if (!module.findPackageJSON) {
throw new Error(`Cannot parse the module format of '${url}' because "module.findPackageJSON" is not available. Upgrade to Node 22.14 to use this feature. This is NOT a bug of Vitest.`)
}
const pkgJsonPath = module.findPackageJSON(url)
const pkgJson = pkgJsonPath ? JSON.parse(readFileSync(pkgJsonPath, 'utf-8')) : {}
if (pkgJson?.type === 'module') {
return 'module'
}
else if (pkgJson?.type === 'commonjs') {
return 'commonjs'
}
else {
// Ambiguous input! Check if it has ESM syntax. Node.js is much smarter here,
// but we don't need to run the code, so we can be more relaxed
if (hasESM(filterOutComments(code))) {
return 'module'
}
else {
return 'commonjs'
}View on GitHub (pinned to d568f8ce37)
Solutions
- Upgrade Node.js to 22.14 or newer.
- Give the target an explicit extension: rename to `.mjs` or `.cjs` so `resolveModuleFormat` short-circuits before needing `findPackageJSON`.
- Provide an explicit factory via `vi.mock(specifier, () => ({ ... }))` to bypass format detection.
Example fix
// before (ambiguous .js, Node < 22.14)
vi.mock('./legacy.js')
// after: explicit extension avoids package.json lookup
vi.mock('./legacy.cjs') Defensive patterns
Strategy: validation
Validate before calling
import module from 'node:module'
const canFindPkg = typeof module.findPackageJSON === 'function'
if (!canFindPkg) {
console.warn(
`vi.mock format detection needs Node >= 22.14 (module.findPackageJSON); current is ${process.version}.`,
)
} Prevention
- Pin Node >= 22.14 in CI and Docker base images.
- Prefer explicit `.mjs`/`.cjs` extensions for files you intend to mock.
- Supply explicit factories when format detection is unreliable.
When it happens
Trigger: Mocking a `.js` dependency whose ESM/CJS nature must be resolved from `package.json`, on Node older than 22.14, hitting the `!module.findPackageJSON` guard at parsers.ts:137.
Common situations: Node 20 LTS in CI; mixed ESM/CJS monorepo where the same specifier resolves differently per package; Docker images built on older Node; upgrading Vitest but not the runtime.
Related errors
- Cannot parse '${filename}' because "module.stripTypeScriptTy
- Cannot spy on export "${String(key)}". Module namespace is n
- require() is not supported in virtual modules. Trying to cal
- Cannot parse '${filename}' because "module.stripTypeScriptTy
- [vitest] Cannot register a mock that is already defined. Exp
AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03).
Data as JSON: /data/errors/ddad2a821a36190e.json.
Report an issue: GitHub.