evanw/esbuild · error · Error
Failed to download
Error message
Failed to download ${JSON.stringify(wasm)} What it means
In the WASM worker (lib/shared/worker.ts:84), `tryToInstantiateModule` fetches the esbuild WebAssembly binary by URL via `fetch(wasm)`. If the response is not ok (`res.ok` is false — any non-2xx status), it throws this error including the JSON-stringified `wasm` value (the URL or module descriptor). This is a download/load failure for the WASM service binary.
Solutions
- Verify the `wasmURL` resolves to a 200 response for the WASM file and that the host permits CORS.
- Bundle the WASM file locally and pass `wasmURL` pointing to a same-origin asset path.
- Pre-fetch the module yourself and pass it via `wasmModule` to avoid esbuild's fetch entirely.
- Check network/CSP policies (connect-src) allow the WASM origin.
Example fix
// before
await esbuild.initialize({ wasmURL: 'https://broken.cdn/esbuild.wasm' });
// after — host locally / preloaded
await esbuild.initialize({ wasmURL: '/assets/esbuild.wasm' });
// or
const mod = await WebAssembly.compile(await (await fetch('/assets/esbuild.wasm')).arrayBuffer());
await esbuild.initialize({ wasmModule: mod }); Defensive patterns
Strategy: retry
Validate before calling
async function loadWasmModule(url: string): Promise<WebAssembly.Module> {
let res = await fetch(url);
if (!res.ok) throw new Error(`Failed to download ${JSON.stringify(url)} (status ${res.status})`);
return WebAssembly.compile(await res.arrayBuffer());
}
const wasmModule = await loadWasmModule('/assets/esbuild.wasm');
await esbuild.initialize({ wasmModule }); Try / catch
try {
await esbuild.initialize({ wasmURL });
} catch (e) {
if (/Failed to download/.test(String(e.message))) { /* retry from a mirror, verify CORS, or preload wasmModule */ }
else throw e;
} Prevention
- Host the WASM file same-origin and pass wasmURL.
- Preload the module and pass wasmModule to bypass esbuild's fetch.
- Ensure CSP connect-src allows the WASM URL.
When it happens
Trigger: Loading esbuild-wasm in a browser/worker where the WASM file URL is wrong, the server returns 404/403/500, the URL points to an unreachable host, or a CSP/network policy blocks the fetch.
Common situations: Misconfigured `wasmURL`/`wasmModule` option; serving the `.wasm` file from a CDN that rate-limits or is unreachable; bundler rewrites that break the asset URL; offline or air-gapped browser; CORS restrictions on the hosting origin.
Related errors
- Cannot use the "serve" API in this environment
- Cannot use the "watch" API in this environment
- Invalid gzip data in archive
- Must provide either the "wasmURL" option or the…
- The "analyzeMetafileSync" API only works in node
AI-assisted analysis of evanw/esbuild@f6058f8364 (2026-08-09).
Data as JSON: /api/errors/871bad35dd778c3e.
Report an issue: GitHub.
Appendix: 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 f6058f8364)