vitest-dev/vitest · error · Error

Invalid data URI

Error message

Invalid data URI

What it means

Thrown by parseDataUri when a `data:` URI imported by test code does not match the strict regex requiring a MIME of text/javascript, application/json, or application/wasm, an optional encoding of charset=utf-8 or base64, and a trailing code segment. Any other scheme, MIME, or malformed structure fails here.

Solutions

  1. Use a supported MIME: `data:text/javascript,...`, `data:application/json,...`, or `data:application/wasm;base64,...`.
  2. Ensure the URI has a comma separating the header from the payload.
  3. For non-JS assets, configure Vite/Vitest to transform or inline them rather than emitting an unsupported data URI.
  4. If the URI is generated by a plugin, update the plugin to emit a supported MIME or a real file URL.

Example fix

// before
import val from 'data:text/plain,hello'

// after
import val from 'data:application/json,' + encodeURIComponent(JSON.stringify('hello'))
Defensive patterns

Strategy: validation

Validate before calling

const DATA_URI_RE = /^data:(?:text\/javascript|application\/json|application\/wasm)(?:;(?:charset=utf-8|base64))?,.*$/
function isSupportedDataUri(uri: string): boolean {
  return DATA_URI_RE.test(uri)
}

Type guard

function isSupportedDataUri(uri: string): boolean {
  return /^data:(?:text\/javascript|application\/json|application\/wasm)(?:;(?:charset=utf-8|base64))?,.+$/s.test(uri)
}

Prevention

When it happens

Trigger: A test (or its dependency graph) imports a `data:` URI with an unsupported MIME (e.g. `data:text/plain,...`, `data:image/png;base64,...`), a missing comma before the payload, or a syntactically broken URI. Reached via EsmExecutor.createDataModule and the sync data-module path.

Common situations: Bundlers/tools emitting `data:` URIs for assets (CSS, images) that Vitest's data-URI handler does not recognize; hand-written data imports with a wrong MIME; a transform producing a malformed data URI.

Related errors


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

Appendix: source

Thrown at packages/vitest/src/runtime/vm/esm-executor.ts:39

// modules); `commit` marks modules the walk owns and should commit to the
// cache — false for cache hits and modules owned by the CJS executor.
type ScratchEntry
  = | { module: VMModule; deps?: undefined; commit: boolean }
    | { module: VMSourceTextModule; deps: string[]; commit: true }

// `hasAsyncGraph` only exists on SourceTextModule — a SyntheticModule is
// synchronous by definition (its evaluation callback is sync)
function moduleHasAsyncGraph(module: VMModule): boolean {
  return module instanceof SourceTextModule && module.hasAsyncGraph()
}

const dataURIRegex
  = /^data:(?<mime>text\/javascript|application\/json|application\/wasm)(?:;(?<encoding>charset=utf-8|base64))?,(?<code>.*)$/

function parseDataUri(identifier: string): { mime: string; code: string | Buffer } {
  const match = identifier.match(dataURIRegex)
  if (!match || !match.groups) {
    throw new Error('Invalid data URI')
  }
  const { mime, encoding } = match.groups
  let code: string | Buffer = match.groups.code
  if (mime === 'application/wasm') {
    if (!encoding) {
      throw new Error('Missing data URI encoding')
    }
    if (encoding !== 'base64') {
      throw new Error(`Invalid data URI encoding: ${encoding}`)
    }
    return { mime, code: Buffer.from(code, 'base64') }
  }
  if (!encoding || encoding === 'charset=utf-8') {
    code = decodeURIComponent(code)
  }
  else if (encoding === 'base64') {
    code = Buffer.from(code, 'base64').toString()
  }

View on GitHub (pinned to 1fa9837ec2)