facebook/flow · error · Error

flow.js wasm export is unavailable

Error message

flow.js wasm export ${name} is unavailable

What it means

Error from flow's flow.js WASM glue: before use, `getWasmExport` looks up required exports by name (with and without a leading underscore, e.g. `main`/`_main` for the dispatch entry point, plus flowDotJsAlloc/Free/StringFree/Call). If the installed WebAssembly module does not expose the expected function, the glue throws, meaning the .wasm binary does not match the JS glue that is driving it.

Solutions

  1. Make the .wasm binary and the JS glue come from the exact same flow version - reinstall/copy them together.
  2. Clear browser/CDN caches (or cache-bust the URL) so both artifacts reload from one version.
  3. Inspect `WebAssembly.Module.exports(module)` and confirm required names (`main`/`_main`, `flowDotJsAlloc`, etc.) are present before installing.
  4. If self-building, export the required functions with the original (unminified) names via emscripten EXPORTED_FUNCTIONS.

Example fix

// before - glue from v0.1, wasm from v0.2
installWasmModule(compileFrom(mixedSource)); // -> wasm export main is unavailable

// after - verify matching artifacts before install
const exports = WebAssembly.Module.exports(mod).map(e => e.name);
if (!exports.includes('main') && !exports.includes('_main')) {
  throw new Error('wasm binary does not match the flow.js glue - redownload both');
}
installWasmModule(mod);
Defensive patterns

Strategy: validation

Validate before calling

function assertWasmExports(wasmModule, required = ['main']) {
  const available = new Set(
    WebAssembly.Module.exports(wasmModule).map(e => e.name),
  );
  for (const name of required) {
    if (!available.has(name) && !available.has('_' + name)) {
      throw new Error(
        `wasm binary missing export '${name}' - glue/wasm version mismatch,` +
        ' redownload both from the same flow version',
      );
    }
  }
}

Try / catch

try {
  installWasmModule(mod);
} catch (e) {
  if (/wasm export .* is unavailable/.test(e.message)) {
    // JS glue and .wasm are from different versions: clear caches,
    // reinstall the matching pair, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the flow wasm install/instantiation path with a WebAssembly.Module built from a different flow version's .wasm (version skew between glue JS and binary), a corrupted or truncated download, or a self-built wasm that did not export the required functions (missing EXPORTED_FUNCTIONS / modularize settings).

Common situations: Mixing a cached flow.js glue script with a newly downloaded flow.wasm (CDN/browser cache mismatch); partially upgrading flow packages so JS and wasm come from different releases; stripping/optimizing the wasm with tools that rename or drop exports.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/0cd20c43ca83a341. Report an issue: GitHub.

Appendix: source

Thrown at src/flow_dot_js_wasm.js:102

    }
  }
  if (typeof wasmExports === 'object' && wasmExports != null) {
    if (typeof wasmExports[underscoredName] === 'function') {
      return wasmExports[underscoredName];
    }
    if (typeof wasmExports[name] === 'function') {
      return wasmExports[name];
    }
  }
  return null;
}

function getWasmExport(wasmModule, name) {
  const wasmExport = findWasmExport(wasmModule, name);
  if (wasmExport != null) {
    return wasmExport;
  }
  throw new Error(`flow.js wasm export ${name} is unavailable`);
}

function updateFlowDotJsMemoryViews() {
  if (typeof updateMemoryViews === 'function') {
    updateMemoryViews();
  }
}

function prepareFlowDotJsFallbackStack() {
  // The non-modular Buck/Emscripten output leaves the default 64KB stack.
  if (
    typeof wasmMemory !== 'object' ||
    wasmMemory == null ||
    typeof stackRestore !== 'function'
  ) {
    return;
  }
  updateFlowDotJsMemoryViews();

View on GitHub (pinned to f88ac94bcf)