vitest-dev/vitest · error · Error

[vitest] Failed to transform ${fileUrl}. Does the file exist

Error message

[vitest] Failed to transform ${fileUrl}. Does the file exist?

What it means

Thrown by ViteExecutor.createViteModule when the VM pool asks Vite (via RPC transform) to compile a module URL but receives no transformed code back. It is the fallback error after the transform either returns an empty result or throws an error that is not a module-load failure. This indicates the file URL could not be resolved/transformed by the Vite server inside the VM worker.

Source

Thrown at packages/vitest/src/runtime/vm/vite-executor.ts:68

          return result.code
        }
      }
      catch (cause: any) {
        // rethrow vite error if it cannot load the module because it's not resolved
        if (
          (typeof cause === 'object' && cause.code === 'ERR_LOAD_URL')
          || (typeof cause?.message === 'string' && cause.message.includes('Failed to load url'))
        ) {
          const error = new Error(
            `Cannot find module '${fileUrl}'`,
            { cause },
          ) as Error & { code: string }
          error.code = 'ERR_MODULE_NOT_FOUND'
          throw error
        }
      }

      throw new Error(
        `[vitest] Failed to transform ${fileUrl}. Does the file exist?`,
      )
    })
  }

  private createViteClientModule() {
    const identifier = CLIENT_ID
    const cached = this.esm.resolveCachedModule(identifier)
    if (cached) {
      return cached
    }
    const stub = this.options.viteClientModule
    const moduleKeys = Object.keys(stub)
    const module = new SyntheticModule(
      moduleKeys,
      function () {
        moduleKeys.forEach((key) => {
          this.setExport(key, stub[key])

View on GitHub (pinned to d568f8ce37)

Solutions

  1. Verify the file at the reported fileUrl actually exists on disk (check spelling, case, extension).
  2. Ensure the file is inside the Vite project root or that server.fs.allow includes its directory in your Vitest config.
  3. Run Vite with debug logging (DEBUG=vite:*) to see why the transform returned no code.
  4. Check that any custom Vite plugins' transform hooks do not throw or swallow the code for that file type.

Example fix

// before: importing a non-existent/typo path
import helper from './src/helpers/tils.ts' // 'utils' misspelled

// after: correct the path
import helper from './src/helpers/utils.ts'
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs'
import { resolve } from 'node:path'

function assertImportResolvable(importSpecifier: string, root: string) {
  if (importSpecifier.startsWith('.') || importSpecifier.startsWith('/')) {
    const target = resolve(root, importSpecifier)
    if (!existsSync(target)) {
      throw new Error(`Cannot resolve import '${importSpecifier}' from root '${root}'`)
    }
  }
}

Prevention

When it happens

Trigger: Running tests with a VM pool (vmThreads/vmForks) where a test file or one of its imports resolves to a file URL that Vite's transform pipeline cannot process. The code path is: createViteModule -> this.options.transform(fileUrl) returns result with no `code`, OR transform throws a non-ERR_LOAD_URL error, then execution falls through to line 68.

Common situations: Importing a file path that does not exist on disk (typo), importing a file outside the Vite project root without configuring server.fs.allow, a Vite plugin whose transform hook throws, or a case-sensitivity mismatch in the import path on case-sensitive filesystems.

Related errors


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