{"record":{"id":"1519bfe614605ebe","repo":"facebook/flow","slug":"flow-dot-js-wasm-requires-crypto-getrandomvalues","errorCode":null,"errorMessage":"flow-dot-js wasm requires crypto.getRandomValues","messagePattern":"flow-dot-js wasm requires crypto\\.getRandomValues","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/flow_dot_js_wasm.js","lineNumber":39,"sourceCode":"var crypto =\n  flowDotJsGlobal.crypto != null &&\n  typeof flowDotJsGlobal.crypto.getRandomValues === 'function'\n    ? flowDotJsGlobal.crypto\n    : {\n        getRandomValues(array) {\n          if (typeof require === 'function') {\n            const nodeCrypto = require('crypto');\n            if (\n              nodeCrypto.webcrypto != null &&\n              typeof nodeCrypto.webcrypto.getRandomValues === 'function'\n            ) {\n              return nodeCrypto.webcrypto.getRandomValues(array);\n            }\n            if (typeof nodeCrypto.randomFillSync === 'function') {\n              return nodeCrypto.randomFillSync(array);\n            }\n          }\n          throw new Error('flow-dot-js wasm requires crypto.getRandomValues');\n        },\n      };\n\nlet flowDotJsWasmModule;\nlet flowDotJsAlloc;\nlet flowDotJsFree;\nlet flowDotJsStringFree;\nlet flowDotJsCall;\nlet flowDotJsReady;\n\nfunction getFlowDotJsGlobal() {\n  return flowDotJsGlobal;\n}\n\nfunction getFlowDotJsExports() {\n  if (typeof module === 'object' && module.exports != null) {\n    return module.exports;\n  }","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/src/flow_dot_js_wasm.js#L21-L57","documentation":"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.","triggerScenarios":"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.","commonSituations":"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`.","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."],"exampleFix":"// before - no crypto in the runtime\nloadFlowWasm(); // -> Error: flow-dot-js wasm requires crypto.getRandomValues\n\n// after - install a polyfill first\nimport 'react-native-getrandom-values'; // or: globalThis.crypto = require('crypto').webcrypto;\nloadFlowWasm();","handlingStrategy":"validation","validationCode":"function hasSecureRandom(): boolean {\n  const g = typeof globalThis !== 'undefined' ? globalThis : self;\n  if (g.crypto && typeof g.crypto.getRandomValues === 'function') return true;\n  try {\n    const c = require('crypto');\n    return !!(c.webcrypto?.getRandomValues ?? c.randomFillSync);\n  } catch {\n    return false;\n  }\n}\n\nif (!hasSecureRandom()) {\n  // install a polyfill BEFORE loading the flow wasm glue\n  globalThis.crypto = globalThis.crypto ?? require('node:crypto').webcrypto;\n}","typeGuard":"function environmentSupportsFlowWasm(): boolean {\n  return hasSecureRandom() && typeof WebAssembly === 'object';\n}","tryCatchPattern":"try {\n  await loadFlowWasm();\n} catch (e) {\n  if (/requires crypto\\.getRandomValues/.test(e.message)) {\n    globalThis.crypto = globalThis.crypto ?? require('node:crypto').webcrypto;\n    await loadFlowWasm(); // one retry after polyfilling\n  } else throw e;\n}","preventionTips":["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."],"tags":["flow","wasm","crypto","webcrypto","environment","polyfill"],"backgroundTag":"missing-webcrypto","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}