{"record":{"id":"53943a0ceef631c2","repo":"facebook/flow","slug":"flowimportto-unexpected-transform-result","errorCode":null,"errorMessage":"flowImportTo: Unexpected transform result.","messagePattern":"flowImportTo: Unexpected transform result\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/flow-api-translator/src/flowImportTo.js","lineNumber":70,"sourceCode":"        case 'DeclareExportAllDeclaration':\n        case 'ExportAllDeclaration':\n        case 'DeclareExportDeclaration':\n        case 'ExportNamedDeclaration': {\n          if (node.source != null) {\n            return SimpleTransform.nodeWith(node, {\n              source: mapSource(node.source),\n            });\n          }\n          return node;\n        }\n        default: {\n          return node;\n        }\n      }\n    },\n  });\n  if (result == null || result.type !== 'Program') {\n    throw new Error('flowImportTo: Unexpected transform result.');\n  }\n  return result;\n}\n","sourceCodeStart":52,"sourceCodeEnd":74,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/packages/flow-api-translator/src/flowImportTo.js#L52-L74","documentation":"flowImportTo runs SimpleTransform.transform over the passed AST and requires the result to be a non-null Program node; anything else is an invalid transform result and throws. The built-in visitor only rewrites module specifiers of import/export declarations, so in practice this throw means the root you passed was not a Program or a custom transform removed the root.","triggerScenarios":"Calling flowImportTo directly (or translateFlowImportsTo) with a non-Program root, e.g. a File wrapper, a Statement, or an AST produced by a prior transform whose root was replaced/removed. Any visitor returning null or an array for the Program node also triggers it.","commonSituations":"Pipelines that chain transforms and accidentally hand flowImportTo a subtree instead of the whole Program; custom forks of the visitor that drop nodes at the root; passing an AST from a different parser whose root type is not 'Program'.","solutions":["Pass the Program node itself: const {type: 'Program'} AST from flow-parser parse(), not a child or wrapper node.","Prefer the public translateFlowImportsTo API, which parses and drives flowImportTo correctly.","If you forked the visitor, ensure every branch (especially for Program) returns a single ESNode, never null or an array.","Add an assertion ast.type === 'Program' before calling to fail with a clearer message."],"exampleFix":"// before\nconst result = flowImportTo(ast.body[0], code, scopeManager, opts);\n\n// after\nconst ast = parse(code, {sourceType: 'module', flow: 'all'});\nconst result = flowImportTo(ast, code, scopeManager, opts);","handlingStrategy":"validation","validationCode":"function isProgram(node) {\n  return node != null && typeof node === 'object' && node.type === 'Program';\n}\n// before calling:\nif (!isProgram(ast)) throw new TypeError('flowImportTo requires the Program node');","typeGuard":"function isProgram(node) {\n  return node != null && typeof node === 'object' && node.type === 'Program';\n}","tryCatchPattern":"try {\n  renamed = flowImportTo(ast, code, scopeManager, {sourceMapper});\n} catch (e) {\n  if (e.message.startsWith('flowImportTo:')) {\n    // root was not a Program or a custom transform removed it\n    throw new Error(`flowImportTo got ${ast?.type ?? 'null'}; pass the parsed Program node`);\n  }\n  throw e;\n}","preventionTips":["Always pass the Program node returned by parse(), never ast.body or a wrapper node.","Prefer the public translateFlowImportsTo API over calling flowImportTo directly.","In forked visitors, guarantee every branch returns a single ESNode for the root."],"tags":["flow","api-translator","ast","transform","imports"],"backgroundTag":"ast-transform-invalid-root","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}