facebook/flow · error · Error

flow-dot-js wasm requires crypto.getRandomValues

Error message

flow-dot-js wasm requires crypto.getRandomValues

What it means

Error from flow's flow.js WASM glue (src/flow_dot_js_wasm.js): the Emscripten-compiled wasm needs `crypto.getRandomValues`. The shim first tries `globalThis.crypto.getRandomValues`, then Node's `require('crypto').webcrypto.getRandomValues`, then `crypto.randomFillSync`. If none exist (no global crypto object and no usable require('crypto')), it throws when the wasm runtime requests randomness.

Solutions

  1. Polyfill `globalThis.crypto.getRandomValues` before loading the wasm (e.g. react-native-get-random-values, or assign a shim backed by any CSPRNG).
  2. In Node, use a version with `crypto.webcrypto` (>= 15) or `randomFillSync` (>= 8) so the built-in fallback works.
  3. In jsdom tests, inject Node's webcrypto: `jsdom(..., {beforeParse(window){ window.crypto = require('crypto').webcrypto; }})`.
  4. Ensure your bundler keeps the `require('crypto')` branch (mark 'crypto' external) instead of dead-code eliminating it.

Example fix

// before - no crypto in the runtime
loadFlowWasm(); // -> Error: flow-dot-js wasm requires crypto.getRandomValues

// after - install a polyfill first
import 'react-native-getrandom-values'; // or: globalThis.crypto = require('crypto').webcrypto;
loadFlowWasm();
Defensive patterns

Strategy: validation

Validate before calling

function hasSecureRandom(): boolean {
  const g = typeof globalThis !== 'undefined' ? globalThis : self;
  if (g.crypto && typeof g.crypto.getRandomValues === 'function') return true;
  try {
    const c = require('crypto');
    return !!(c.webcrypto?.getRandomValues ?? c.randomFillSync);
  } catch {
    return false;
  }
}

if (!hasSecureRandom()) {
  // install a polyfill BEFORE loading the flow wasm glue
  globalThis.crypto = globalThis.crypto ?? require('node:crypto').webcrypto;
}

Type guard

function environmentSupportsFlowWasm(): boolean {
  return hasSecureRandom() && typeof WebAssembly === 'object';
}

Try / catch

try {
  await loadFlowWasm();
} catch (e) {
  if (/requires crypto\.getRandomValues/.test(e.message)) {
    globalThis.crypto = globalThis.crypto ?? require('node:crypto').webcrypto;
    await loadFlowWasm(); // one retry after polyfilling
  } else throw e;
}

Prevention

When it happens

Trigger: Loading the flow.js wasm module in a runtime without WebCrypto: IE11/legacy browsers (only `msCrypto`), a custom JS runtime with no crypto global and no CommonJS require, React Native without a polyfill, or a jsdom/browser-like test environment where `globalThis.crypto` was never installed and `require` is unavailable.

Common situations: Running the flow.devtools/flow.js wasm bundle in sandboxed or exotic environments; bundling the glue with a bundler that drops the `require('crypto')` fallback; environments that stub `crypto` without a working `getRandomValues`.

Related errors


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

Appendix: source

Thrown at src/flow_dot_js_wasm.js:39

var crypto =
  flowDotJsGlobal.crypto != null &&
  typeof flowDotJsGlobal.crypto.getRandomValues === 'function'
    ? flowDotJsGlobal.crypto
    : {
        getRandomValues(array) {
          if (typeof require === 'function') {
            const nodeCrypto = require('crypto');
            if (
              nodeCrypto.webcrypto != null &&
              typeof nodeCrypto.webcrypto.getRandomValues === 'function'
            ) {
              return nodeCrypto.webcrypto.getRandomValues(array);
            }
            if (typeof nodeCrypto.randomFillSync === 'function') {
              return nodeCrypto.randomFillSync(array);
            }
          }
          throw new Error('flow-dot-js wasm requires crypto.getRandomValues');
        },
      };

let flowDotJsWasmModule;
let flowDotJsAlloc;
let flowDotJsFree;
let flowDotJsStringFree;
let flowDotJsCall;
let flowDotJsReady;

function getFlowDotJsGlobal() {
  return flowDotJsGlobal;
}

function getFlowDotJsExports() {
  if (typeof module === 'object' && module.exports != null) {
    return module.exports;
  }

View on GitHub (pinned to f88ac94bcf)