evanw/esbuild · error · Error
Failed to download ${JSON.stringify(wasm)}
Error message
Failed to download ${JSON.stringify(wasm)} What it means
In the browser/wasm worker (lib/shared/worker.ts), when esbuild is given a wasm URL string instead of a precompiled WebAssembly.Module, it fetches that URL and at lib/shared/worker.ts:90 throws if the response is not ok (non-2xx). The message echoes the wasm URL via JSON.stringify. This is the browser bootstrap path: the worker downloads esbuild.wasm, and any network failure (404, CORS, offline, wrong base URL) surfaces here.
Source
Thrown at lib/shared/worker.ts:90
instance => {
postMessage(null)
go.run(instance)
},
error => {
postMessage(error)
},
)
return go
}
async function tryToInstantiateModule(wasm: WebAssembly.Module | string, go: Go): Promise<WebAssembly.Instance> {
if (wasm instanceof WebAssembly.Module) {
return WebAssembly.instantiate(wasm, go.importObject)
}
const res = await fetch(wasm)
if (!res.ok) throw new Error(`Failed to download ${JSON.stringify(wasm)}`)
// Attempt to use the superior "instantiateStreaming" API first
if ('instantiateStreaming' in WebAssembly && /^application\/wasm($|;)/i.test(res.headers.get('Content-Type') || '')) {
const result = await WebAssembly.instantiateStreaming(res, go.importObject)
return result.instance
}
// Otherwise, fall back to the inferior "instantiate" API
const bytes = await res.arrayBuffer()
const result = await WebAssembly.instantiate(bytes, go.importObject)
return result.instance
}
View on GitHub (pinned to 6ff1d8b0d8)
Solutions
- Verify the wasm URL resolves (open it in the browser network tab) and returns 200 with Content-Type application/wasm.
- Host esbuild.wasm same-origin or ensure the serving origin sends Access-Control-Allow-Origin.
- Pass a precompiled WebAssembly.Module (compiled via WebAssembly.compile) to bypass the fetch entirely.
- If using a bundler, ensure the .wasm file is emitted to the output directory (copy-webpack-plugin, vite static asset handling).
Example fix
// before
import * as esbuild from 'esbuild-wasm';
await esbuild.initialize({ wasmURL: 'https://cdn.example/esbuild.wasm' }); // 404
// after — local asset + module
import wasmUrl from 'esbuild-wasm/esbuild.wasm?url';
await esbuild.initialize({ wasmURL: wasmUrl });
// or precompile:
const resp = await fetch(wasmUrl);
const mod = await WebAssembly.compile(await resp.arrayBuffer());
await esbuild.initialize({ wasmModule: mod }); Defensive patterns
Strategy: try-catch
Validate before calling
async function loadEsbuildWasm(wasmURL) {
const resp = await fetch(wasmURL, { method: 'HEAD' });
if (!resp.ok && resp.status !== 405) {
throw new Error(`esbuild wasm not reachable at ${wasmURL} (status ${resp.status})`);
}
// ok to proceed
} Type guard
function isWasmModule(v): v is WebAssembly.Module {
return typeof WebAssembly !== 'undefined' && v instanceof WebAssembly.Module;
} Try / catch
try {
await esbuild.initialize({ wasmURL });
} catch (e) {
if (/Failed to download/.test(e.message)) {
// precompile and retry with a module to bypass fetch
const r = await fetch(wasmURL);
const mod = await WebAssembly.compile(await r.arrayBuffer());
await esbuild.initialize({ wasmModule: mod });
} else throw e;
} Prevention
- Precompile the wasm module (WebAssembly.compile) and pass wasmModule to skip the fetch path entirely.
- Ensure the .wasm asset is emitted alongside JS by your bundler (copy-webpack-plugin, Vite ?url).
- Host wasm same-origin or send proper CORS headers; check the Network tab for 200 + application/wasm.
When it happens
Trigger: Initializing esbuild-wasm in the browser where the wasm asset path is wrong (missing CDN file, 404). CORS blocking the fetch because the server didn't send Access-Control-Allow-Origin. Offline development / network blocked. Serving wasm from a path that requires a base href the bundler didn't set.
Common situations: Vite/Webpack copies JS but not the .wasm file; the fetch 404s. CDN URL points to a tag that was unpublished. Browser blocks cross-origin wasm fetch without CORS headers. Service worker intercepts and returns a non-2xx.
Related errors
- Must provide either the "wasmURL" option or the "wasmModule"
- The "write" option is unavailable in this environment
- The "serve" API is not supported when using WebAssembly
- The "buildSync" API only works in node
- The "transformSync" API only works in node
AI-assisted analysis of evanw/esbuild@6ff1d8b0d8 (2026-08-03).
Data as JSON: /data/errors/871bad35dd778c3e.json.
Report an issue: GitHub.