facebook/flow · error
sourceType option must be "script", "module", or…
Error message
sourceType option must be "script", "module", or "unambiguous" if set
What it means
getOptions in the oxidized flow-parser validates sourceType when set: it must be 'script', 'module', or 'unambiguous' ('unambiguous' is then cleared so detection happens during parsing). Any other string — 'commonjs', 'esm', '' — throws before a parse starts.
Solutions
- Map module-system names to parser values: 'esm' -> 'module', 'commonjs' -> 'script', auto -> 'unambiguous'.
- Omit sourceType entirely if you want the parser default rather than sending '' or null.
- Validate/whitelist sourceType at your own API boundary before calling parse().
Example fix
// before
parse(code, {sourceType: pkgType /* 'commonjs' or 'module' from package.json */});
// after
const sourceType = pkgType === 'module' ? 'module' : 'script';
parse(code, {sourceType}); Defensive patterns
Strategy: validation
Validate before calling
const SOURCE_TYPES = new Set(['script', 'module', 'unambiguous']);
function isValidSourceType(v) {
return v == null || SOURCE_TYPES.has(v);
} Type guard
function isSourceTypeOption(v) {
return v == null || v === 'script' || v === 'module' || v === 'unambiguous';
} Prevention
- Map module-system names (esm/commonjs) to parser names (module/script) at the config layer.
- Omit sourceType rather than passing '' when you want the default.
When it happens
Trigger: parse(code, {sourceType: 'commonjs'}) or other non-enum values, commonly forwarded from user configuration or from tools whose sourceType vocabulary differs (Babel uses 'unambiguous'|'module'|'script', but configs often carry 'commonjs'/'esm' module-system fields that get passed by mistake).
Common situations: Config plumbing where package.json "type" or bundler settings ('commonjs'/'esm') are mapped directly to parser sourceType; typos; passing undefined-via-empty-string defaults.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- flow option must be "all" or "detect"
- Cannot insert array into non-array parent type
- createTranslationContext: Module scope not found
- Expected parent node to be set on
- flow-remove-types: the "checkPragma" option has been…
AI-assisted analysis of facebook/flow@5c86586199 (2026-08-20).
Data as JSON: /api/errors/d582e00971798fc1.
Report an issue: GitHub.
Appendix: source
Thrown at packages/flow-parser/oxidized-src/index.js:51
// results — earlier versions wrote normalized fields back onto `opts`,
// poisoning subsequent calls.
const options: ParserOptions = {...DEFAULTS, ...(opts ?? {})};
// Default to detecting whether to parse Flow syntax by the presence
// of an @flow pragma.
if (options.flow !== 'all' && options.flow !== 'detect') {
throw new Error('flow option must be "all" or "detect"');
}
if (options.sourceType === 'unambiguous') {
// Clear source type so that it will be detected from the contents of the file
delete options.sourceType;
} else if (
options.sourceType != null &&
options.sourceType !== 'script' &&
options.sourceType !== 'module'
) {
throw new Error(
'sourceType option must be "script", "module", or "unambiguous" if set',
);
}
if (options.enableExperimentalComponentSyntax == null) {
options.enableExperimentalComponentSyntax = true; // Enable by default
}
if (options.enableExperimentalFlowMatchSyntax == null) {
options.enableExperimentalFlowMatchSyntax = true; // Enable by default
}
// Record syntax: upstream defaults `enableExperimentalFlowRecordSyntax` to
// `true`. The fork's WASM cwrap (FlowParser.js) reads `options.enableRecords`
// — a separate, OCaml-aligned key intentionally mirroring
// `default_parse_options`. To preserve the upstream-compatible API surface
// on the outside while keeping the OCaml-aligned key on the WASM boundary,
// bridge: default the upstream key, then mirror it onto the cwrap key. TheView on GitHub (pinned to 5c86586199)