vitejs/vite · error · Error

Failed to parse WASM file

Error message

Failed to parse WASM file "${wasmFilePath}": ${(e as Error).message}

What it means

parseWasm reads the .wasm file and runs WebAssembly.compile plus Module.imports/exports to discover its import/export surface for glue generation. If compile or introspection throws (corrupt binary, truncated file, unsupported wasm feature), Vite rethrows with the wasm file path and the underlying error message as cause.

Solutions

  1. Inspect the underlying error (e.cause) for the exact WebAssembly error (e.g. 'magic number' mismatch means wrong file type).
  2. Rebuild/re-download the wasm from source and confirm the byte size matches.
  3. Ensure the runtime/Node version supports the wasm features the module uses.
  4. Verify the file is genuinely wasm (xxd the first bytes for the magic 0x00 0x61 0x73 0x6d).

Example fix

// before — file is corrupt or wrong type saved as .wasm
import wasm from './pkg/my.wasm'
// after — regenerate the wasm from source (e.g.)
// wasm-pack build --target web
// then confirm header bytes are 00 61 73 6d
Defensive patterns

Strategy: validation

Validate before calling

import { readFileSync } from 'node:fs'
function assertValidWasm(file) {
  const buf = readFileSync(file)
  const isWasm = buf.length >= 4 && buf[0]===0x00 && buf[1]===0x61 && buf[2]===0x73 && buf[3]===0x6d
  if (!isWasm) throw new Error(`${file} is not a valid wasm module (bad magic)`)
}

Type guard

function hasWasmMagic(buf: Uint8Array): boolean {
  return buf.length >= 4 && buf[0]===0x00 && buf[1]===0x61 && buf[2]===0x73 && buf[3]===0x6d
}

Try / catch

try {
  return await parseWasm(file)
} catch (e) {
  logger.error(`WASM parse failed for ${file}: ${e.cause?.message ?? e.message}`)
  throw e
}

Prevention

When it happens

Trigger: Importing a .wasm file that is not a valid WebAssembly module: truncated download, wrong file type saved with a .wasm extension, a wasm using features the runtime rejects, or a zero-byte/corrupt file. parseWasm runs during the wasm plugin's transform of the importing module.

Common situations: Broken build artifact, git-lfs not pulling the binary, copy error leaving a partial file, or a wasm produced by a toolchain version emitting extensions (e.g. reference types) the host WebAssembly does not support.

Understand the failure class

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/95835fce87442db6. Report an issue: GitHub.

Appendix: source

Thrown at packages/vite/src/node/plugins/wasm.ts:263

    const importMap = new Map<string, WasmName[]>()
    for (const item of WebAssembly.Module.imports(wasmModule)) {
      if (wasmReservedModules.has(item.module)) continue
      let names = importMap.get(item.module)
      if (!names) importMap.set(item.module, (names = []))
      names.push({ name: item.name, isGlobal: item.kind === 'global' })
    }
    const imports = [...importMap].map(([from, names]) => ({ from, names }))

    let hasGlobalExport = false
    const exports = WebAssembly.Module.exports(wasmModule).map((item) => {
      const isGlobal = item.kind === 'global'
      if (isGlobal) hasGlobalExport = true
      return { name: item.name, isGlobal }
    })

    return { imports, exports, hasGlobalExport }
  } catch (e) {
    throw new Error(
      `Failed to parse WASM file "${wasmFilePath}": ${(e as Error).message}`,
      { cause: e },
    )
  }
}

// Instantiates the wasm module and re-exports its exports verbatim. Globals stay
// WebAssembly.Global objects so wasm-to-wasm global imports get the live cell.
function generateInstanceGlue(
  wasmInfo: WasmInfo,
  names: { initWasm: string; wasmUrl: string },
): string {
  const importStatements: string[] = []
  const importObject: SimpleObject = wasmInfo.imports.map(
    ({ from, names: importNames }, i) => {
      const value: SimpleObject = []
      const globals = importNames.filter((n) => n.isGlobal)
      const others = importNames.filter((n) => !n.isGlobal)

View on GitHub (pinned to b4d66fee14)