facebook/flow · error · Error

flow.js wasm is still loading; await flow.ready first.

Error message

flow.js wasm is still loading; await flow.ready first.

What it means

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.

Source

Thrown at src/flow_dot_js_wasm.js:212

        Module.onRuntimeInitialized = function () {
          if (typeof onRuntimeInitialized === 'function') {
            onRuntimeInitialized();
          }
          finish();
        };
      }
    });
  }
  return flowDotJsReady;
}

function initWasm() {
  if (flowDotJsWasmModule != null) {
    return;
  }
  loadWasm();
  if (flowDotJsWasmModule == null) {
    throw new Error('flow.js wasm is still loading; await flow.ready first.');
  }
}

function callRust(method, params) {
  initWasm();
  const request = encodeUtf8(JSON.stringify({method, params}));
  const requestPtr = flowDotJsAlloc(request.length);
  updateFlowDotJsMemoryViews();
  let responsePtr = 0;
  try {
    flowDotJsWasmModule.HEAPU8.set(request, requestPtr);
    responsePtr = flowDotJsCall(requestPtr, request.length);
    updateFlowDotJsMemoryViews();
    const response = JSON.parse(decodeHeapString(responsePtr));
    if (!response.ok) {
      throw new Error(response.error);
    }
    return response.value;

View on GitHub (pinned to d1341dac89)

Solutions

  1. Await the readiness promise once before the first API call: await flow.ready.
  2. In tests, gate the suite: beforeAll(async () => { await flow.ready; }).
  3. Wrap wasm-backed calls in an async function so callers always await; treat flow.ready as a hard dependency of every entry point.
  4. If you must fail loudly on misuse, check flow readiness via the exported promise rather than relying on this throw.

Example fix

// before
const flow = require('./flow_dot_js_wasm.js');
const result = flow.someWasmMethod(params); // throws: still loading

// after
const flow = require('./flow_dot_js_wasm.js');
async function main() {
  await flow.ready;
  const result = flow.someWasmMethod(params);
}
Defensive patterns

Strategy: validation

Validate before calling

const flow = require('./flow_dot_js_wasm.js');

async function callWhenReady(method, params) {
  if (flow.ready != null) {
    await flow.ready; // resolves once the wasm module is installed
  }
  return flow[method](params);
}

Try / catch

try {
  const result = flow.someWasmMethod(params);
} catch (err) {
  if (err instanceof Error && err.message.includes('await flow.ready first')) {
    // re-enter asynchronously after initialization completes
    await flow.ready;
    return flow.someWasmMethod(params);
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of facebook/flow@d1341dac89 (2026-08-17). Data as JSON: /api/errors/fed679af756547e1. Report an issue: GitHub.