facebook/flow · error · Error
ImportDeclaration should appear when the mode is ES6 and in
Error message
ImportDeclaration should appear when the mode is ES6 and in the module context.
What it means
In flow-eslint's scope Referencer (an eslint-scope port), visiting an ImportDeclaration requires the scope manager to have been created with ecmaVersion >= 6 (isES6) and sourceType 'module' (isModule). If the analyzed source contains an import statement but analysis was not configured for ES modules, this invariant throws.
Source
Thrown at packages/flow-eslint/src/scope-manager/referencer/Referencer.js:668
this.visitFunction(node);
}
FunctionExpression(node: FunctionExpression): void {
this.visitFunction(node);
}
Identifier(node: Identifier): void {
this.currentScope().referenceValue(node);
this.visitType(node.typeAnnotation);
}
ImportAttribute(_: ImportAttribute): void {
// import assertions are module metadata and thus have no variables to reference
}
ImportDeclaration(node: ImportDeclaration): void {
if (!this.scopeManager.isES6() || !this.scopeManager.isModule()) {
throw new Error(
'ImportDeclaration should appear when the mode is ES6 and in the module context.',
);
}
ImportVisitor.visit(this, node);
}
JSXAttribute(node: JSXAttribute): void {
this.visit(node.value);
}
JSXClosingElement(node: JSXClosingElement): void {
/**
* Note that this was not previously considered to be a reference and that
* other scope analyzers do not count them either: e.g. TypeScript-eslint
* https://fburl.com/4q93a3x3
*
* We are considering this a reference because it technically includes anView on GitHub (pinned to d1341dac89)
Solutions
- Set `parserOptions: { ecmaVersion: 'latest', sourceType: 'module' }` in your eslint/analysis config
- If the file really is a CommonJS script, remove the import statements rather than changing the config
- When constructing the scope analysis programmatically, pass the same ecmaVersion/sourceType you passed the parser
Example fix
// before (.eslintrc.js)
module.exports = { rules: { /* ... */ } };
// after (.eslintrc.js)
module.exports = {
parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
rules: { /* ... */ },
}; Defensive patterns
Strategy: validation
Validate before calling
function isEsmAnalysisConfig(parserOptions: {
ecmaVersion?: number | 'latest';
sourceType?: string;
}): boolean {
const ecma = parserOptions?.ecmaVersion ?? 5;
const ecmaNum = ecma === 'latest' ? 2022 : Number(ecma);
return parserOptions?.sourceType === 'module' && ecmaNum >= 2015;
} Type guard
function canAnalyzeImports(opts: {ecmaVersion?: unknown; sourceType?: unknown}): boolean {
const ecma = opts.ecmaVersion == null ? 5 : opts.ecmaVersion === 'latest' ? 2022 : Number(opts.ecmaVersion);
return opts.sourceType === 'module' && ecma >= 2015;
} Prevention
- Always set sourceType and ecmaVersion when linting ESM
- Verify effective config with `eslint --print-config file.js`
- Pass the exact parserOptions object to the scope analysis when embedding the Referencer
When it happens
Trigger: Running flow-eslint or equivalent scope analysis with parserOptions missing `sourceType: 'module'` (default is 'script') or with ecmaVersion below 2015, while the analyzed code contains import/export statements.
Common situations: Missing or partial parserOptions in .eslintrc; lint setups switched to ESM files without config updates; embedding the Referencer in custom tooling and forgetting to pass the parser's options to the scope manager.
Related errors
- import/export cannot be inserted into a ${insertionParent.pa
- import/export cannot be replaced into a ${replacementParent.
AI-assisted analysis of facebook/flow@d1341dac89 (2026-08-17).
Data as JSON: /api/errors/bebbf3ff8d443e86.
Report an issue: GitHub.