{"record":{"id":"24734ba32f036c3e","repo":"facebook/flow","slug":"parser-out-of-memory","errorCode":null,"errorMessage":"Parser out of memory","messagePattern":"Parser out of memory","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/flow-parser/oxidized-src/FlowParser.js","lineNumber":206,"sourceCode":"  // non-ambient defaults.\n  const filename =\n    typeof options.sourceFilename === 'string' ? options.sourceFilename : '';\n  const filenameBuffer =\n    filename.length > 0 ? Buffer.from(filename, 'utf8') : null;\n\n  // All wasm allocations live inside a single try/finally so a throw from\n  // any malloc, copyToHeap, or the parse call itself frees everything we\n  // managed to allocate. Earlier versions allocated and partially populated\n  // before entering the try, so a throw from copyToHeap leaked the wasm\n  // address back to the heap.\n  let sourceAddr = 0;\n  let filenameAddr = 0;\n  let filenameLen = 0;\n  let parseResult = 0;\n  try {\n    sourceAddr = FlowParserWASM._malloc(sourceBuffer.length + 1);\n    if (!sourceAddr) {\n      throw new Error('Parser out of memory');\n    }\n    if (filenameBuffer != null) {\n      filenameAddr = FlowParserWASM._malloc(filenameBuffer.length + 1);\n      if (!filenameAddr) {\n        throw new Error('Parser out of memory');\n      }\n      copyToHeap(filenameBuffer, filenameAddr);\n      filenameLen = filenameBuffer.length + 1;\n    }\n    copyToHeap(sourceBuffer, sourceAddr);\n\n    // `enableTypes` mirrors OCaml's `types` option, which defaults to true.\n    // Fixtures opt out via `types: false` to exercise the no-type-grammar\n    // path (e.g. ts_syntax fixtures testing that `as`/`satisfies` are not\n    // parsed when types are disabled).\n    const enableTypes = options.enableTypes === false ? 0 : 1;\n    // `sourceType` is sent to Rust as an integer code:\n    //   0 = unspecified / parser default","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/facebook/flow/blob/d1341dac899a79c027762f6b423d896045287620/packages/flow-parser/oxidized-src/FlowParser.js#L188-L224","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Skip pathological inputs: enforce a source-size threshold (e.g. 5-10 MB) and report oversized files separately instead of parsing them","For legitimately huge generated files, split them or use the native flow CLI parser instead of the wasm build","Confirm you pass a string, not a Buffer/Uint8Array, so lengths match expectations"],"exampleFix":"// before\nconst ast = parse(fs.readFileSync(file, 'utf8'));\n\n// after — guard pathological inputs\nconst MAX = 8 * 1024 * 1024; // 8 MB\nconst src = fs.readFileSync(file, 'utf8');\nif (src.length > MAX) throw new RangeError(`${file} too large to parse`);\nconst ast = parse(src);","handlingStrategy":"validation","validationCode":"const MAX_SOURCE_BYTES = 8 * 1024 * 1024; // 8 MB ceiling\n\nfunction safeToParse(source: unknown): boolean {\n  return typeof source === 'string' && source.length < MAX_SOURCE_BYTES;\n}\n\n// if (!safeToParse(src)) skip and report the file instead of parsing","typeGuard":"function isParseableSource(source: unknown): source is string {\n  return typeof source === 'string' && source.length < 8 * 1024 * 1024;\n}","tryCatchPattern":"try {\n  const ast = parse(source);\n} catch (err) {\n  if (err.message === 'Parser out of memory') {\n    // skip this file with a warning; do not retry the same input unchanged\n    report.skipped(file, 'source too large for wasm parser');\n  } else throw err;\n}","preventionTips":["Enforce a source-size limit before parsing","Exclude generated/vendor/bundle directories from parsing","Always pass a string, never a Buffer, to avoid inflated lengths"],"tags":["flow-parser","wasm","memory","large-files"],"backgroundTag":"parser-out-of-memory","analyzedSha":"d1341dac899a79c027762f6b423d896045287620","analyzedAt":"2026-08-17T00:07:02.212Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}