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
- Polyfill `globalThis.crypto.getRandomValues` before loading the wasm (e.g. react-native-get-random-values, or assign a shim backed by any CSPRNG).
- In Node, use a version with `crypto.webcrypto` (>= 15) or `randomFillSync` (>= 8) so the built-in fallback works.
- In jsdom tests, inject Node's webcrypto: `jsdom(..., {beforeParse(window){ window.crypto = require('crypto').webcrypto; }})`.
- 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
- Polyfill globalThis.crypto.getRandomValues in RN/legacy-browser bundles before importing the wasm glue.
- Keep 'crypto' external in bundler configs so the Node fallback survives.
- Prefer Node >= 15 (webcrypto) or >= 8 (randomFillSync) on the server.
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
- flow.js wasm export is unavailable
- Parser out of memory
- Attempted to insert a statement into
- Cannot get hostname
- Cannot insert array into non-array parent type
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)