{"record":{"id":"e9ffe57b4eabdcd6","repo":"facebook/flow","slug":"import-export-cannot-be-replaced-into-a-replacem","errorCode":null,"errorMessage":"import/export cannot be replaced into a ${replacementParent.parent.type}.","messagePattern":"import/export cannot be replaced into a (.+?)\\.","errorType":"validation","errorClass":"InvalidReplacementError","httpStatus":null,"severity":"error","filePath":"packages/flow-transform/src/transform/mutations/ReplaceStatementWithMany.js","lineNumber":63,"sourceCode":"    nodesToReplaceWith,\n    keepComments: options?.keepComments ?? false,\n  };\n}\n\nexport function performReplaceStatementWithManyMutation(\n  mutationContext: MutationContext,\n  mutation: ReplaceStatementWithManyMutation,\n): ESNode {\n  const replacementParent = getStatementParent(mutation.target);\n\n  // enforce that if we are replacing with module declarations - they are being inserted in a valid location\n  if (\n    !isValidModuleDeclarationParent(\n      replacementParent.parent,\n      mutation.nodesToReplaceWith,\n    )\n  ) {\n    throw new InvalidReplacementError(\n      `import/export cannot be replaced into a ${replacementParent.parent.type}.`,\n    );\n  }\n\n  mutationContext.markDeletion(mutation.target);\n  mutationContext.markMutation(replacementParent.parent, replacementParent.key);\n\n  if (mutation.keepComments) {\n    // attach comments to the very first replacement node\n    moveCommentsToNewNode(mutation.target, mutation.nodesToReplaceWith[0]);\n  }\n\n  if (replacementParent.type === 'array') {\n    const parent: interface {\n      [string]: ReadonlyArray<DetachedNode<Statement | ModuleDeclaration>>,\n    } = replacementParent.parent;\n    parent[replacementParent.key] = astArrayMutationHelpers.replaceInArray(\n      parent[replacementParent.key],","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/packages/flow-transform/src/transform/mutations/ReplaceStatementWithMany.js#L45-L81","documentation":"InvalidReplacementError thrown by flow-transform's replaceStatementWithMany when the replacement nodes include an import/export (ModuleDeclaration) but the statement being replaced does not live where module declarations are legal. The same `isValidModuleDeclarationParent` check as insertStatement applies: only `Program` (or a BlockStatement inside `DeclareModule`) may receive module declarations.","triggerScenarios":"`mutate.replaceStatementWithMany(nestedStmt, [detachedImport, ...])` where nestedStmt.parent is a function BlockStatement, SwitchCase consequent, or IfStatement branch - i.e. replacing a non-top-level statement with an import/export.","commonSituations":"Codemods converting a nested statement to a module import (e.g. replacing an inner require() call's statement with an import); forgetting to hoist when replacing a statement that sits inside a function body.","solutions":["Split the operation: replace the nested statement with non-module statements, and insert the import separately relative to a top-level Program.body statement.","Only replace-with-imports when `stmt.parent.type === 'Program'`.","Collect imports during traversal and emit them once at Program level."],"exampleFix":"// before\nmutate.replaceStatementWithMany(nestedStmt, [buildImport(), buildStatement()]); // throws\n\n// after\nmutate.replaceStatementWithMany(nestedStmt, [buildStatement()]);\nmutate.insertStatementBefore(firstTopLevelStmt, buildImport());","handlingStrategy":"type-guard","validationCode":"function canReplaceWithModuleDeclarations(anchor) {\n  const p = anchor.parent;\n  return p.type === 'Program' ||\n    (p.type === 'BlockStatement' && p.parent?.type === 'DeclareModule');\n}\n\nif (newNodes.some(isModuleDeclaration) && !canReplaceWithModuleDeclarations(anchor)) {\n  // split: hoist module declarations to Program level\n  const stmts = newNodes.filter(n => !isModuleDeclaration(n));\n  mutate.replaceStatementWithMany(anchor, stmts);\n  mutate.insertStatementBefore(firstTopLevelStatement, moduleNodes[0]);\n} else {\n  mutate.replaceStatementWithMany(anchor, newNodes);\n}","typeGuard":"function isModuleDeclaration(n): boolean {\n  return ['ImportDeclaration', 'ExportNamedDeclaration',\n    'ExportDefaultDeclaration', 'ExportAllDeclaration'].includes(n.type);\n}","tryCatchPattern":null,"preventionTips":["Only replace-with-imports at Program level (or DeclareModule blocks).","Hoist imports: collect them during traversal, emit once against a Program.body anchor."],"tags":["flow","flow-transform","codemod","imports","module-declaration","ast-mutation"],"backgroundTag":"invalid-ast-mutation","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}