{"record":{"id":"d582e00971798fc1","repo":"facebook/flow","slug":"sourcetype-option-must-be-script-module-or","errorCode":null,"errorMessage":"sourceType option must be \"script\", \"module\", or \"unambiguous\" if set","messagePattern":"sourceType option must be \"script\", \"module\", or \"unambiguous\" if set","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/flow-parser/oxidized-src/index.js","lineNumber":52,"sourceCode":"  // results — earlier versions wrote normalized fields back onto `opts`,\n  // poisoning subsequent calls.\n  const options: ParserOptions = {...DEFAULTS, ...(opts ?? {})};\n\n  // Default to detecting whether to parse Flow syntax by the presence\n  // of an @flow pragma.\n  if (options.flow !== 'all' && options.flow !== 'detect') {\n    throw new Error('flow option must be \"all\" or \"detect\"');\n  }\n\n  if (options.sourceType === 'unambiguous') {\n    // Clear source type so that it will be detected from the contents of the file\n    delete options.sourceType;\n  } else if (\n    options.sourceType != null &&\n    options.sourceType !== 'script' &&\n    options.sourceType !== 'module'\n  ) {\n    throw new Error(\n      'sourceType option must be \"script\", \"module\", or \"unambiguous\" if set',\n    );\n  }\n\n  if (options.enableExperimentalComponentSyntax == null) {\n    options.enableExperimentalComponentSyntax = true; // Enable by default\n  }\n\n  if (options.enableExperimentalFlowMatchSyntax == null) {\n    options.enableExperimentalFlowMatchSyntax = true; // Enable by default\n  }\n\n  // Record syntax: upstream defaults `enableExperimentalFlowRecordSyntax` to\n  // `true`. The fork's WASM cwrap (FlowParser.js) reads `options.enableRecords`\n  // — a separate, OCaml-aligned key intentionally mirroring\n  // `default_parse_options`. To preserve the upstream-compatible API surface\n  // on the outside while keeping the OCaml-aligned key on the WASM boundary,\n  // bridge: default the upstream key, then mirror it onto the cwrap key. The","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/facebook/flow/blob/d1341dac899a79c027762f6b423d896045287620/packages/flow-parser/oxidized-src/index.js#L34-L70","documentation":"The second options check in the Flow parser: when sourceType is provided it must be 'script', 'module', or 'unambiguous' ('unambiguous' is normalized away and auto-detected from file contents). Any other string throws.","triggerScenarios":"Calling parse(code, {sourceType: 'commonjs'}) or 'esm'/'es6' — none are accepted; feeding values in from other tools' configs.","commonSituations":"Porting options from Babel or other parsers; passing tsconfig's `module: \"commonjs\"` value straight into parser options; typos like 'modules'.","solutions":["Use 'module' for ESM, 'script' for CommonJS/global scripts, 'unambiguous' to auto-detect, or omit the option","Build parser options explicitly instead of reusing config objects from tsconfig/Babel"],"exampleFix":"// before\nparse(source, { sourceType: 'commonjs' });\n\n// after\nparse(source, { sourceType: 'script' }); // CommonJS files are scripts","handlingStrategy":"validation","validationCode":"const SOURCE_TYPES = new Set(['script', 'module', 'unambiguous']);\n\nfunction validSourceType(opts: {sourceType?: unknown}): boolean {\n  return opts?.sourceType == null || SOURCE_TYPES.has(opts.sourceType as string);\n}","typeGuard":"function isSourceType(\n  v: unknown,\n): v is 'script' | 'module' | 'unambiguous' | undefined {\n  return v == null || v === 'script' || v === 'module' || v === 'unambiguous';\n}","tryCatchPattern":"try {\n  parse(source, opts);\n} catch (err) {\n  if (err.message.includes('sourceType option must be')) {\n    const {sourceType, ...rest} = opts; // drop invalid value, use default\n    parse(source, rest);\n  } else throw err;\n}","preventionTips":["Map tsconfig module values to parser sourceTypes explicitly ('commonjs' → 'script')","Build parser options in one place, not by reusing foreign config objects"],"tags":["flow-parser","options","source-type","validation"],"backgroundTag":"invalid-option-value","analyzedSha":"d1341dac899a79c027762f6b423d896045287620","analyzedAt":"2026-08-17T00:07:02.212Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}