{"id":"871bad35dd778c3e","repo":"evanw/esbuild","slug":"failed-to-download-json-stringify-wasm","errorCode":null,"errorMessage":"Failed to download ${JSON.stringify(wasm)}","messagePattern":"Failed to download (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"lib/shared/worker.ts","lineNumber":90,"sourceCode":"    instance => {\n      postMessage(null)\n      go.run(instance)\n    },\n    error => {\n      postMessage(error)\n    },\n  )\n\n  return go\n}\n\nasync function tryToInstantiateModule(wasm: WebAssembly.Module | string, go: Go): Promise<WebAssembly.Instance> {\n  if (wasm instanceof WebAssembly.Module) {\n    return WebAssembly.instantiate(wasm, go.importObject)\n  }\n\n  const res = await fetch(wasm)\n  if (!res.ok) throw new Error(`Failed to download ${JSON.stringify(wasm)}`)\n\n  // Attempt to use the superior \"instantiateStreaming\" API first\n  if ('instantiateStreaming' in WebAssembly && /^application\\/wasm($|;)/i.test(res.headers.get('Content-Type') || '')) {\n    const result = await WebAssembly.instantiateStreaming(res, go.importObject)\n    return result.instance\n  }\n\n  // Otherwise, fall back to the inferior \"instantiate\" API\n  const bytes = await res.arrayBuffer()\n  const result = await WebAssembly.instantiate(bytes, go.importObject)\n  return result.instance\n}\n","sourceCodeStart":72,"sourceCodeEnd":103,"githubUrl":"https://github.com/evanw/esbuild/blob/6ff1d8b0d8c134e867a397eef39702a223ebef9e/lib/shared/worker.ts#L72-L103","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\nimport * as esbuild from 'esbuild-wasm';\nawait esbuild.initialize({ wasmURL: 'https://cdn.example/esbuild.wasm' }); // 404\n\n// after — local asset + module\nimport wasmUrl from 'esbuild-wasm/esbuild.wasm?url';\nawait esbuild.initialize({ wasmURL: wasmUrl });\n// or precompile:\nconst resp = await fetch(wasmUrl);\nconst mod = await WebAssembly.compile(await resp.arrayBuffer());\nawait esbuild.initialize({ wasmModule: mod });","handlingStrategy":"try-catch","validationCode":"async function loadEsbuildWasm(wasmURL) {\n  const resp = await fetch(wasmURL, { method: 'HEAD' });\n  if (!resp.ok && resp.status !== 405) {\n    throw new Error(`esbuild wasm not reachable at ${wasmURL} (status ${resp.status})`);\n  }\n  // ok to proceed\n}","typeGuard":"function isWasmModule(v): v is WebAssembly.Module {\n  return typeof WebAssembly !== 'undefined' && v instanceof WebAssembly.Module;\n}","tryCatchPattern":"try {\n  await esbuild.initialize({ wasmURL });\n} catch (e) {\n  if (/Failed to download/.test(e.message)) {\n    // precompile and retry with a module to bypass fetch\n    const r = await fetch(wasmURL);\n    const mod = await WebAssembly.compile(await r.arrayBuffer());\n    await esbuild.initialize({ wasmModule: mod });\n  } else throw e;\n}","preventionTips":["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."],"tags":["wasm","browser","network","initialization","cors"],"analyzedSha":"6ff1d8b0d8c134e867a397eef39702a223ebef9e","analyzedAt":"2026-08-03T19:42:38.433Z","schemaVersion":2}