{"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/d1341dac899a79c027762f6b423d896045287620/src/flow_dot_js_wasm.js#L21-L57","documentation":"The flow.js wasm glue needs a source of randomness (WebAssembly heap setup / hash seeding). It first uses globalThis.crypto.getRandomValues, then falls back to require('crypto') trying webcrypto.getRandomValues and randomFillSync; only when all of these are unavailable does it throw. Hitting it means the runtime exposes neither WebCrypto nor Node's crypto module — typically a stripped sandbox runtime or a bundled environment where 'crypto' was shimmed away.","triggerScenarios":"Loading flow_dot_js_wasm.js in a runtime without WebCrypto and without a working require('crypto') (QuickJS/duktape-style sandboxes, some edge/lambda-like isolation layers); bundling for a browser where a bundler stubs the node 'crypto' import to an empty module while the page also lacks globalThis.crypto; extremely old Node builds predating both webcrypto and randomFillSync.","commonSituations":"Webpack/browserify builds where require('crypto') resolves to an empty shim; executing the module inside restricted CI sandboxes that whitelist modules; older embedded JS engines; Electron/main processes with patched globals.","solutions":["Run on a runtime with WebCrypto: any modern browser over HTTPS or Node.js >= 15 (earlier Node versions still work via randomFillSync).","Before the module loads, install a polyfill: globalThis.crypto = {getRandomValues: (arr) => arr.fill(...)} backed by a real CSPRNG of the host.","In bundlers, alias the 'crypto' import to a real polyfill package (e.g. crypto-browserify) instead of an empty stub.","If the environment truly has no CSPRNG, host the wasm call behind a small service instead of running it in-process."],"exampleFix":"// before\n// loaded in a sandbox: no globalThis.crypto, no require('crypto') -> throws\nconst flow = require('./flow_dot_js_wasm.js');\n\n// after\n// install a polyfill backed by the host's CSPRNG first\nconst nodeCrypto = require('crypto');\nglobalThis.crypto = nodeCrypto.webcrypto;\nconst flow = require('./flow_dot_js_wasm.js');","handlingStrategy":"fallback","validationCode":"function hasSecureRandom() {\n  if (globalThis.crypto?.getRandomValues != null) return true;\n  try {\n    const c = require('crypto');\n    return c?.webcrypto?.getRandomValues != null || c?.randomFillSync != null;\n  } catch {\n    return false;\n  }\n}\n\nif (!hasSecureRandom()) {\n  throw new Error('This environment cannot run flow.js wasm: no crypto.getRandomValues');\n}","typeGuard":null,"tryCatchPattern":"let flow;\ntry {\n  flow = require('./flow_dot_js_wasm.js');\n} catch (err) {\n  if (err.message === 'flow-dot-js wasm requires crypto.getRandomValues') {\n    // polyfill with the host CSPRNG, then retry the load once\n    globalThis.crypto = require('crypto').webcrypto;\n    flow = require('./flow_dot_js_wasm.js');\n  } else {\n    throw err;\n  }\n}","preventionTips":["Run on Node >= 15 or a modern browser so WebCrypto is always present.","In bundlers, alias 'crypto' to a real polyfill rather than an empty stub.","Add a startup feature check for crypto.getRandomValues in restricted runtimes."],"tags":["wasm","flow","crypto","environment","polyfill"],"backgroundTag":"missing-web-crypto","analyzedSha":"d1341dac899a79c027762f6b423d896045287620","analyzedAt":"2026-08-17T00:07:02.212Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}