{"record":{"id":"fed679af756547e1","repo":"facebook/flow","slug":"flow-js-wasm-is-still-loading-await-flow-ready-fi","errorCode":null,"errorMessage":"flow.js wasm is still loading; await flow.ready first.","messagePattern":"flow\\.js wasm is still loading; await flow\\.ready first\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/flow_dot_js_wasm.js","lineNumber":212,"sourceCode":"        Module.onRuntimeInitialized = function () {\n          if (typeof onRuntimeInitialized === 'function') {\n            onRuntimeInitialized();\n          }\n          finish();\n        };\n      }\n    });\n  }\n  return flowDotJsReady;\n}\n\nfunction initWasm() {\n  if (flowDotJsWasmModule != null) {\n    return;\n  }\n  loadWasm();\n  if (flowDotJsWasmModule == null) {\n    throw new Error('flow.js wasm is still loading; await flow.ready first.');\n  }\n}\n\nfunction callRust(method, params) {\n  initWasm();\n  const request = encodeUtf8(JSON.stringify({method, params}));\n  const requestPtr = flowDotJsAlloc(request.length);\n  updateFlowDotJsMemoryViews();\n  let responsePtr = 0;\n  try {\n    flowDotJsWasmModule.HEAPU8.set(request, requestPtr);\n    responsePtr = flowDotJsCall(requestPtr, request.length);\n    updateFlowDotJsMemoryViews();\n    const response = JSON.parse(decodeHeapString(responsePtr));\n    if (!response.ok) {\n      throw new Error(response.error);\n    }\n    return response.value;","sourceCodeStart":194,"sourceCodeEnd":230,"githubUrl":"https://github.com/facebook/flow/blob/d1341dac899a79c027762f6b423d896045287620/src/flow_dot_js_wasm.js#L194-L230","documentation":"Wasm instantiation is asynchronous (loadWasm() stores the in-flight promise in flowDotJsReady and exposes it as flow.ready), but callRust() must run synchronously. initWasm() therefore kicks off loading if needed and immediately throws when the module is not installed yet. The message tells you the exact remedy: await the flow.ready promise before invoking any wasm-backed API. Note that even after you await it once elsewhere, calling during module evaluation or before the await resolves still triggers this.","triggerScenarios":"Calling a wasm-backed method (anything routed through callRust, e.g. flow version checks, parse/check/lint style entry points) synchronously right after require/import without awaiting flow.ready; fire-and-forget usage inside a synchronous initializer; test code that calls the API in the test body while a sibling test awaits flow.ready later.","commonSituations":"First call at application startup racing module init; converting sync scripts to use the wasm build; tests missing an async beforeAll; code paths shared between the sync native build and the async wasm build.","solutions":["Await the readiness promise once before the first API call: await flow.ready.","In tests, gate the suite: beforeAll(async () => { await flow.ready; }).","Wrap wasm-backed calls in an async function so callers always await; treat flow.ready as a hard dependency of every entry point.","If you must fail loudly on misuse, check flow readiness via the exported promise rather than relying on this throw."],"exampleFix":"// before\nconst flow = require('./flow_dot_js_wasm.js');\nconst result = flow.someWasmMethod(params); // throws: still loading\n\n// after\nconst flow = require('./flow_dot_js_wasm.js');\nasync function main() {\n  await flow.ready;\n  const result = flow.someWasmMethod(params);\n}","handlingStrategy":"validation","validationCode":"const flow = require('./flow_dot_js_wasm.js');\n\nasync function callWhenReady(method, params) {\n  if (flow.ready != null) {\n    await flow.ready; // resolves once the wasm module is installed\n  }\n  return flow[method](params);\n}","typeGuard":null,"tryCatchPattern":"try {\n  const result = flow.someWasmMethod(params);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('await flow.ready first')) {\n    // re-enter asynchronously after initialization completes\n    await flow.ready;\n    return flow.someWasmMethod(params);\n  }\n  throw err;\n}","preventionTips":["Await flow.ready once at startup before any wasm-backed call.","Gate test suites with beforeAll(async () => { await flow.ready; }).","Route every wasm-backed entry point through an async wrapper so callers cannot bypass the readiness check."],"tags":["wasm","flow","async","initialization","race-condition"],"backgroundTag":"async-init-not-awaited","analyzedSha":"d1341dac899a79c027762f6b423d896045287620","analyzedAt":"2026-08-17T00:07:02.212Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}