vitest-dev/vitest · error · Error

automocking files with `export *` is not supported because i

Error message

automocking files with `export *` is not supported because it cannot be easily statically analysed

What it means

Thrown at packages/mocker/src/node/automock.ts:41-48 when automockModule encounters an ExportAllDeclaration (export * from '...') and options.id is not set. Resolving the re-exported module's exports requires reading the source from disk via options.id (import.meta.resolve at automock.ts:55), so without an id the re-export cannot be statically analyzed and automocking aborts.

Source

Thrown at packages/mocker/src/node/automock.ts:45

  }
  catch (cause) {
    if (options.id) {
      throw new Error(`failed to parse ${options.id}`, { cause })
    }
    throw cause
  }

  const m = new MagicString(code)

  const allSpecifiers: { name: string; alias?: string }[] = []
  const replacers: (() => void)[] = []
  let importIndex = 0
  for (const _node of ast.body) {
    if (_node.type === 'ExportAllDeclaration') {
      const node = _node as Positioned<ExportAllDeclaration>
      // TODO: pass it down in the browser mode
      if (!options.id) {
        throw new Error(
          `automocking files with \`export *\` is not supported because it cannot be easily statically analysed`,
        )
      }

      const source = node.source.value
      if (typeof source !== 'string') {
        throw new TypeError(`unknown source type while automocking: ${source}`)
      }

      const moduleUrl = import.meta.resolve(source, pathToFileURL(options.id).toString())
      const modulePath = fileURLToPath(moduleUrl)
      const moduleContent = readFileSync(modulePath, 'utf-8')
      const transformedCode = transformCode(moduleContent, moduleUrl)
      const moduleFormat = resolveModuleFormat(moduleUrl, transformedCode)
      const moduleExports = collectModuleExports(modulePath, transformedCode, moduleFormat || 'module')
      replacers.push(() => {
        const importNames: string[] = []
        moduleExports.forEach((exportName) => {

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Provide an explicit factory so automock parsing is skipped: vi.mock('./barrel', () => ({ ... })).
  2. Mock the individual modules the barrel re-exports instead of the barrel itself.
  3. Ensure options.id is passed when invoking automockModule directly (node path passes id; browser path may not).

Example fix

// before
vi.mock('./index') // index has `export * from './users'`

// after
vi.mock('./index', () => ({
  getUser: vi.fn(),
}))
Defensive patterns

Strategy: validation

Validate before calling

// Detect export * in the target before automocking and fall back to a factory.
import { readFileSync } from 'node:fs'
function hasExportStar(file: string): boolean {
  return /export\s+\*\s+from/.test(readFileSync(file, 'utf-8'))
}

if (hasExportStar('./barrel.ts')) {
  vi.mock('./barrel.ts', () => ({ /* explicit exports */ }))
} else {
  vi.mock('./barrel.ts')
}

Try / catch

try {
  vi.mock('./barrel.ts')
} catch (e) {
  if (e instanceof Error && /export \*/.test(e.message)) {
    vi.mock('./barrel.ts', () => ({ /* explicit exports */ }))
  } else { throw e }
}

Prevention

When it happens

Trigger: Automocking a module that contains `export * from './other'` when automockModule is called without options.id. The browser path historically omits id, hence the TODO comment about browser mode.

Common situations: Automocking a barrel/index file that re-exports everything; automocking in browser mode where id is not forwarded; mocking a library entry that uses export *.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/10f80f83c6200f03.json. Report an issue: GitHub.