vitest-dev/vitest · error · Error

Cannot parse the module format of

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

Thrown by `resolveModuleFormat` in the node-side automock parser when a file has a `.js`/`.ts`/or extensionless path and `module.findPackageJSON` is unavailable on the running Node.js. To determine whether such a file is ESM or CommonJS, Vitest reads the nearest `package.json` `type` field via Node's native `module.findPackageJSON` (added in Node 22.14.0). Without it, the format is ambiguous and automock cannot proceed safely.

Solutions

  1. Upgrade Node.js to 22.14.0 or newer.
  2. Rename the target file to `.mjs`/`.mts` (forces ESM) or `.cjs`/`.cts` (forces CommonJS) so `resolveModuleFormat` short-circuits without `findPackageJSON`.
  3. Provide an explicit `vi.mock(path, factory)` to bypass automock analysis.

Example fix

// before — ambiguous .js module on Node < 22.14
vi.mock('./mod.js')
// after — explicit ESM extension, or upgrade Node to >= 22.14
// rename mod.js -> mod.mjs, or:
vi.mock('./mod.js', () => ({ fn: vi.fn() }))
Defensive patterns

Strategy: validation

Validate before calling

// Check Node version before automocking ambiguous-extension modules.
import Module from 'node:module'
function canFindPackageJSON(): boolean {
  return typeof (Module as any).findPackageJSON === 'function'
}
if (!canFindPackageJSON()) {
  // use explicit factories, or rename files to .mjs/.cjs to force a format
}

Type guard

function nodeSupportsFindPackageJSON(): boolean {
  return typeof (require('node:module') as any).findPackageJSON === 'function'
}

Prevention

When it happens

Trigger: Automocking a `.js` or extensionless module whose package type must be read from `package.json`, while running Node.js older than 22.14.0. Triggered during automock export analysis when `resolveModuleFormat` is called for the target file or any of its `export *` re-exports.

Common situations: Node 20 LTS or early Node 22 in CI/local; automocking a `.js` file in a `"type": "module"` or `"type": "commonjs"` package; automocking a dependency that re-exports from other `.js` files.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/ddad2a821a36190e. Report an issue: GitHub.

Appendix: 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 1fa9837ec2)