vitest-dev/vitest · error · Error

Cannot automock ' ' because it failed to parse.

Error message

Cannot automock '${url}' because it failed to parse.

What it means

When Vitest automocks a module (`vi.mock('mod')` with no factory, or `{ spy: true }`), it parses the module's source with acorn to enumerate exports, then synthesizes mocked values. If acorn cannot parse the transformed source, this error wraps the parse failure (original attached as `cause`). The catch is at nativeModuleMocker.ts:113-115.

Solutions

  1. Inspect `error.cause` for the precise parse error and location.
  2. Provide an explicit factory to skip automock parsing: `vi.mock('mod', () => ({ ... }))`.
  3. Use `vi.mock('mod', { spy: true })` only if the module's runtime exports are introspectable.
  4. Fix or simplify the syntax in the target module so acorn (ECMA latest) accepts it after TypeScript stripping.
  5. If the module is third-party, prefer mocking at a higher level or aliasing to an ESM build.

Example fix

// before
vi.mock('./decorated-module') // automock fails to parse decorators

// after
vi.mock('./decorated-module', () => ({
  doThing: vi.fn(),
}))
Defensive patterns

Strategy: try-catch

Validate before calling

try { parse(transformedSource, { sourceType: 'module', ecmaVersion: 'latest' }) } catch (e) { throw new Error('automock will fail; provide an explicit factory') }

Type guard

null

Try / catch

try { vi.mock('./mod') } catch (e) { if (/Cannot automock.*failed to parse/.test(e.message)) { vi.mock('./mod', () => ({ known: vi.fn() })) } else throw e }

Prevention

When it happens

Trigger: Calling `vi.mock('mod')` (automock) on a module whose source — after TypeScript stripping — is invalid JavaScript for acorn: uses syntax acorn rejects (e.g. decorators, stage-2 proposals without the right plugin), contains a syntax error, or the transformed source is empty/malformed. The `automockModule` call at nativeModuleMocker.ts:94-102 does the parse.

Common situations: Automocking a module with non-standard syntax not supported by acorn's latest ecmaVersion; mocking a built-in whose source synthesis is fine but a re-exported module fails; the module has a genuine syntax error that only surfaces under automock; `.stripTypeScriptTypes` produced output acorn still rejects (e.g. `enum` remnants).

Understand the failure class

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/moduleRunner/nativeModuleMocker.ts:114

        mockType,
        code => parse(code, {
          sourceType: 'module',
          ecmaVersion: 'latest',
        }),
        { id: moduleId },
      )
      const transformed = ms.toString()
      const map = ms.generateMap({ hires: 'boundary', source: moduleId })
      const code = `${transformed}\n//# sourceMappingURL=${genSourceMapUrl(map)}`

      return {
        format: 'module',
        source: code,
        shortCircuit: true,
      }
    }
    catch (cause) {
      throw new Error(`Cannot automock '${url}' because it failed to parse.`, { cause })
    }
  }

  public loadManualMock(url: string, result: module.LoadFnOutput): module.LoadFnOutput | undefined {
    const filename = url.startsWith('file://') ? fileURLToPath(url) : url
    const moduleId = cleanUrl(normalizeModuleId(filename))
    const mockedModule = this.getDependencyMock(moduleId)
    // should not be possible
    if (mockedModule?.type !== 'manual') {
      console.warn(`Vitest detected unregistered manual mock ${moduleId}. This is a bug in Vitest. Please, open a new issue with reproduction.`)
      return
    }

    if (isBuiltin(moduleId)) {
      const builtinModule = getBuiltinModule(toBuiltin(moduleId))
      const exports = Object.keys(builtinModule)
      const manualMockedModule = createManualModuleSource(moduleId, exports)

View on GitHub (pinned to 1fa9837ec2)