facebook/flow · error · Error
updatePendingStatements: Variable parent of
Error message
updatePendingStatements: Variable parent of "${dep}" not found What it means
Companion to error 3 in the same loop: the dependency's Variable was found in context.variableMap, but one of its scope definitions has def.node == null, so translation cannot locate the AST statement that defines it and throws. It indicates the variable exists in the module scope without an attached defining node (implicit/ambient definitions rather than a concrete declaration).
Solutions
- Replace reliance on implicit globals with explicit declarations (`declare var require: any;` style) or imports in the input file.
- Run with recoverFromErrors: true to let the translator emit error comments and continue.
- Isolate the dependency named in the message and inspect how it is defined; rewrite it as a normal top-level declaration.
- Report the repro upstream if the definition is a plain top-level statement, since def.node should then be set.
Example fix
// before
exports.make = () => require('./util'); // implicit module/require
// after
import util from './util';
export const make = () => util; Defensive patterns
Strategy: try-catch
Validate before calling
// Detect dependencies whose defs lack a defining node before translating
function depsWithMissingDefNode(context, deps) {
return deps.filter((d) => {
const v = context.variableMap.get(d);
return v == null || v.defs.some((def) => def.node == null);
});
} Type guard
function hasConcreteDefs(variable) {
return variable != null && variable.defs.length > 0 && variable.defs.every((d) => d.node != null);
} Try / catch
try {
const {code: out} = await translateFlowToFlowDef({code, recoverFromErrors: true});
} catch (e) {
const m = /Variable parent of "(.+)" not found/.exec(e.message);
if (m) {
report(`"${m[1]}" resolves to an implicit/ambient definition — rewrite it as an explicit top-level declaration`);
return;
}
throw e;
} Prevention
- Avoid implicit globals (require/module/exports, UMD React) as dependencies of exported declarations.
- Convert CommonJS usage to ESM imports before extracting libdefs.
- Enable recoverFromErrors in batch tooling and log the dependency name from the message.
When it happens
Trigger: translateFlowToFlowDef input whose dependency resolves to a module-scope Variable whose defs array contains a Definition with a null node (implicit globals, injected builtins like require/module, or scope-analysis artifacts), so getTopLevelStatement has no statement to enqueue.
Common situations: Converting files that use CommonJS injected names (require, module, exports) or ambient implicit globals as dependencies of exported declarations; scope-manager versions whose Definition.node is optional for some def types.
Related errors
- updatePendingStatements: Variable for dependency
- createTranslationContext: Module scope not found
- unable to resolve scope
- CommonJS exports cannot be combined with ES module exports.
- flowImportTo: Unexpected transform result.
AI-assisted analysis of facebook/flow@21c11b2ead (2026-08-20).
Data as JSON: /api/errors/3355006d2f2694b4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/flow-api-translator/src/flowToFlowDef.js:425
const seenDeps = new Set<Dep>();
const processedStatements = new Set<ProgramStatement>();
const pendingStatements = new Set<ProgramStatement>();
function updatePendingStatements(deps: TranslatedDeps): void {
for (const dep of deps) {
if (seenDeps.has(dep)) {
continue;
}
seenDeps.add(dep);
const variable = context.variableMap.get(dep);
if (variable == null) {
throw new Error(
`updatePendingStatements: Variable for dependency "${dep}" not found`,
);
}
for (const def of variable.defs) {
const stmt = def.node;
if (stmt == null) {
throw new Error(
`updatePendingStatements: Variable parent of "${dep}" not found`,
);
}
const topLevelStmt = getTopLevelStatement(stmt, context);
if (processedStatements.has(topLevelStmt)) {
continue;
}
pendingStatements.add(topLevelStmt);
}
}
}
function updateProcessedStatement(stmt: ProgramStatement): void {
processedStatements.add(stmt);
pendingStatements.delete(stmt);
}
// Process all export statements
for (const stmt of ast.body) {View on GitHub (pinned to 21c11b2ead)