facebook/flow · error · Error

Parser out of memory

Error message

Parser out of memory

What it means

The wasm Flow parser allocates linear memory for the source (and optional filename) via FlowParserWASM._malloc; wasm malloc returns 0 on failure and the parser throws 'Parser out of memory'. All allocations sit in a try/finally so partial allocations are freed.

Source

Thrown at packages/flow-parser/oxidized-src/FlowParser.js:206

  // non-ambient defaults.
  const filename =
    typeof options.sourceFilename === 'string' ? options.sourceFilename : '';
  const filenameBuffer =
    filename.length > 0 ? Buffer.from(filename, 'utf8') : null;

  // All wasm allocations live inside a single try/finally so a throw from
  // any malloc, copyToHeap, or the parse call itself frees everything we
  // managed to allocate. Earlier versions allocated and partially populated
  // before entering the try, so a throw from copyToHeap leaked the wasm
  // address back to the heap.
  let sourceAddr = 0;
  let filenameAddr = 0;
  let filenameLen = 0;
  let parseResult = 0;
  try {
    sourceAddr = FlowParserWASM._malloc(sourceBuffer.length + 1);
    if (!sourceAddr) {
      throw new Error('Parser out of memory');
    }
    if (filenameBuffer != null) {
      filenameAddr = FlowParserWASM._malloc(filenameBuffer.length + 1);
      if (!filenameAddr) {
        throw new Error('Parser out of memory');
      }
      copyToHeap(filenameBuffer, filenameAddr);
      filenameLen = filenameBuffer.length + 1;
    }
    copyToHeap(sourceBuffer, sourceAddr);

    // `enableTypes` mirrors OCaml's `types` option, which defaults to true.
    // Fixtures opt out via `types: false` to exercise the no-type-grammar
    // path (e.g. ts_syntax fixtures testing that `as`/`satisfies` are not
    // parsed when types are disabled).
    const enableTypes = options.enableTypes === false ? 0 : 1;
    // `sourceType` is sent to Rust as an integer code:
    //   0 = unspecified / parser default

View on GitHub (pinned to d1341dac89)

Solutions

  1. Skip pathological inputs: enforce a source-size threshold (e.g. 5-10 MB) and report oversized files separately instead of parsing them
  2. For legitimately huge generated files, split them or use the native flow CLI parser instead of the wasm build
  3. Confirm you pass a string, not a Buffer/Uint8Array, so lengths match expectations

Example fix

// before
const ast = parse(fs.readFileSync(file, 'utf8'));

// after — guard pathological inputs
const MAX = 8 * 1024 * 1024; // 8 MB
const src = fs.readFileSync(file, 'utf8');
if (src.length > MAX) throw new RangeError(`${file} too large to parse`);
const ast = parse(src);
Defensive patterns

Strategy: validation

Validate before calling

const MAX_SOURCE_BYTES = 8 * 1024 * 1024; // 8 MB ceiling

function safeToParse(source: unknown): boolean {
  return typeof source === 'string' && source.length < MAX_SOURCE_BYTES;
}

// if (!safeToParse(src)) skip and report the file instead of parsing

Type guard

function isParseableSource(source: unknown): source is string {
  return typeof source === 'string' && source.length < 8 * 1024 * 1024;
}

Try / catch

try {
  const ast = parse(source);
} catch (err) {
  if (err.message === 'Parser out of memory') {
    // skip this file with a warning; do not retry the same input unchanged
    report.skipped(file, 'source too large for wasm parser');
  } else throw err;
}

Prevention

When it happens

Trigger: Parsing a source string so large that the wasm module's linear memory cannot satisfy sourceBuffer.length+1 bytes — typically files of many tens of MB, or memory pressure where the wasm heap is near its cap; also passing a Buffer where a string is expected, inflating the length.

Common situations: Machine-generated, bundled, or concatenated giant files; accidentally reading binaries or lockfiles into the parser; constrained CI containers; 32-bit wasm builds with low memory ceilings.

Related errors


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