vitest-dev/vitest · error · Error

Failed to import test file

Error message

Failed to import test file ${filepath}

What it means

Thrown by the browser runner when the dynamic `import()` of a test file fails. The runner constructs an import URL (`/<filepath>?browserv=<hash>`, with `@fs/` prefix on Windows paths) and lets Vite transform it; if Vite/the browser cannot resolve, transform, or execute the module, the import promise rejects. The original rejection is attached as `cause` so the underlying syntax/resolution/runtime error is preserved.

Solutions

  1. Inspect `error.cause` (printed in the Vitest report) — it holds the real module load/transform error.
  2. Fix the underlying syntax/import error in the test file or its dependencies.
  3. Run `pnpm install` if a package is missing; clear the Vite cache (`node_modules/.vite`) if stale.
  4. Confirm the path is served by the Vite dev server (no typos, correct case, inside `root`).

Example fix

// error.cause: Cannot find module '@/utils'
// before
import { x } from '@/utils'

// after (fix the path / install the package)
import { x } from './utils'
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: resolve the test file the same way Vite would
try {
  await import(/* @vite-ignore */ testFilePath)
} catch (e) {
  console.error('Test file will fail to import:', e)
}

Try / catch

// the runner already wraps the import; surface error.cause to the user
try {
  await runTests()
} catch (err) {
  const cause = (err as Error & { cause?: Error }).cause
  if (cause) console.error('Underlying import error:', cause)
  throw err
}

Prevention

When it happens

Trigger: A syntax error in the test file; an import of a module that does not exist or is not installed; a Vite transform error (e.g. invalid TypeScript, unsupported syntax for the target); a circular/failed setup-file import; the file path being inaccessible on the Vite server.

Common situations: New dependency not yet installed (`pnpm install`); typo in an import path; using a Node-only API in a browser test; TypeScript types referencing a missing module; stale Vite cache after upgrading.

Related errors


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

Appendix: source

Thrown at packages/browser/src/client/tester/runner.ts:349

      if (mode === 'setup' || !hash) {
        hash = Date.now().toString()
        this.hashMap.set(filepath, hash)
      }

      // on Windows we need the unit to resolve the test file
      const prefix = `/${/^\w:/.test(filepath) ? '@fs/' : ''}`
      const query = `browserv=${hash}`
      const importpath = `${prefix}${filepath}?${query}`.replace(/\/+/g, '/')
      // start tracing before the test file is imported
      const trace = this.config.browser.trace
      if (mode === 'collect' && trace !== 'off') {
        await this.commands.triggerCommand('__vitest_startTracing', [])
      }
      try {
        await import(/* @vite-ignore */ importpath)
      }
      catch (err) {
        throw new Error(`Failed to import test file ${filepath}`, { cause: err })
      }

      if (mode === 'collect' && !this.sourceMapPrefetches.has(filepath)) {
        // the file is transformed now, so the server can hand out its map;
        // request it early so onBeforeRunSuite doesn't have to wait
        this.sourceMapPrefetches.set(
          filepath,
          rpc().getBrowserFileSourceMap(filepath).catch(() => undefined),
        )
      }
    }

    trace = <T>(name: string, attributes: Record<string, any> | (() => T), cb?: () => T): T => {
      const options: import('@opentelemetry/api').SpanOptions = typeof attributes === 'object' ? { attributes } : {}
      return this._otel.$(`vitest.test.runner.${name}`, options, cb || attributes as () => T)
    }
  }
}

View on GitHub (pinned to 1fa9837ec2)