{"record":{"id":"0cd20c43ca83a341","repo":"facebook/flow","slug":"flow-js-wasm-export-name-is-unavailable","errorCode":null,"errorMessage":"flow.js wasm export ${name} is unavailable","messagePattern":"flow\\.js wasm export (.+?) is unavailable","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/flow_dot_js_wasm.js","lineNumber":102,"sourceCode":"    }\n  }\n  if (typeof wasmExports === 'object' && wasmExports != null) {\n    if (typeof wasmExports[underscoredName] === 'function') {\n      return wasmExports[underscoredName];\n    }\n    if (typeof wasmExports[name] === 'function') {\n      return wasmExports[name];\n    }\n  }\n  return null;\n}\n\nfunction getWasmExport(wasmModule, name) {\n  const wasmExport = findWasmExport(wasmModule, name);\n  if (wasmExport != null) {\n    return wasmExport;\n  }\n  throw new Error(`flow.js wasm export ${name} is unavailable`);\n}\n\nfunction updateFlowDotJsMemoryViews() {\n  if (typeof updateMemoryViews === 'function') {\n    updateMemoryViews();\n  }\n}\n\nfunction prepareFlowDotJsFallbackStack() {\n  // The non-modular Buck/Emscripten output leaves the default 64KB stack.\n  if (\n    typeof wasmMemory !== 'object' ||\n    wasmMemory == null ||\n    typeof stackRestore !== 'function'\n  ) {\n    return;\n  }\n  updateFlowDotJsMemoryViews();","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/facebook/flow/blob/d1341dac899a79c027762f6b423d896045287620/src/flow_dot_js_wasm.js#L84-L120","documentation":"The glue resolves the wasm module's callable entry points by looking for both `_<name>` and bare `name` properties (findWasmExport) and getWasmExport throws when neither exists. It fires during module installation when the loaded Emscripten module lacks an expected export such as the flowDotJsAlloc/flowDotJsCall dispatch functions or the 'main' fallback used by installWasmModule. The usual cause is a mismatch between the generated JS glue and the .wasm sidecar binary — different build versions, a truncated/corrupt binary, or a stale artifact left next to a newer one.","triggerScenarios":"Mixing a flow.js wasm glue JS from one release with a .wasm sidecar from another (partial upgrade, stale node_modules or build dir); a truncated .wasm file (interrupted download/build) that instantiates partially; symbol renaming between Buck/Emscripten builds so the expected export names no longer exist.","commonSituations":"Incremental build caches that regenerate raw-js but reuse an old .wasm; deployments where only some artifacts were updated; downstream packagers (see flow_dot_js_wasm_packager.js) that pair mismatched raw-js and wasm inputs; local hacks renaming exported symbols.","solutions":["Clean and rebuild (or reinstall) so the generated glue JS and the .wasm sidecar come from the exact same build.","Verify the .wasm file is intact: correct size, starts with the wasm magic bytes (\\0asm).","Delete stale artifacts (old .wasm next to new .js, or vice versa) in build output and node_modules before rebuilding.","If you control the build, confirm the export names (flowDotJsAlloc/flowDotJsFree/flowDotJsStringFree/flowDotJsCall or the 'main' dispatch fallback) are still emitted."],"exampleFix":"# before: mixed artifacts from two builds\nls out/  # flow_dot_js.js (v0.2), flow_dot_js.wasm (v0.1, stale)\n\n# after: rebuild both artifacts together\nrm -rf out/ && ./build.sh  # regenerates matching .js and .wasm","handlingStrategy":"try-catch","validationCode":"const fs = require('fs');\n\nfunction wasmSidecarLooksIntact(rawJsPath, wasmPath) {\n  if (!fs.existsSync(wasmPath)) return false;\n  const head = fs.readFileSync(wasmPath).subarray(0, 4);\n  return head[0] === 0x00 && head[1] === 0x61 && head[2] === 0x73 && head[3] === 0x6d; // \\0asm\n}","typeGuard":null,"tryCatchPattern":"// after loadWasm/ready resolves, or around first wasm call\ntry {\n  await flow.ready;\n} catch (err) {\n  if (err instanceof Error && /wasm export .* is unavailable/.test(err.message)) {\n    // glue JS and .wasm sidecar are from different builds; clean and rebuild\n    console.error('Stale wasm artifacts: rebuild so raw-js and .wasm match.');\n    process.exitCode = 1;\n  } else {\n    throw err;\n  }\n}","preventionTips":["Always generate the glue JS and .wasm sidecar in the same build; never mix versions.","Clean build output and node_modules before rebuilding wasm artifacts.","Verify the .wasm magic bytes and file size as a cheap integrity check in CI."],"tags":["wasm","flow","build","version-mismatch","emscripten"],"backgroundTag":"wasm-module-incompatibility","analyzedSha":"d1341dac899a79c027762f6b423d896045287620","analyzedAt":"2026-08-17T00:07:02.212Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}