{"record":{"id":"7c798af046e16c52","repo":"facebook/flow","slug":"cannot-insert-array-into-non-array-parent-type","errorCode":null,"errorMessage":"Cannot insert array into non-array parent type: ${parent.type}","messagePattern":"Cannot insert array into non-array parent type: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/flow-parser/oxidized-src/transform/astNodeMutationHelpers.js","lineNumber":105,"sourceCode":"  const replacementParent = getParentKey(\n    originalNode,\n    originalNodeParent,\n    visitorKeys,\n  );\n  const parent = replacementParent.node;\n  if (replacementParent.type === 'array') {\n    // $FlowExpectedError[prop-missing]\n    parent[replacementParent.key] = replaceInArray(\n      // $FlowExpectedError[prop-missing]\n      parent[replacementParent.key],\n      replacementParent.targetIndex,\n      Array.isArray(nodeToReplaceWith)\n        ? nodeToReplaceWith\n        : [nodeToReplaceWith],\n    );\n  } else {\n    if (Array.isArray(nodeToReplaceWith)) {\n      throw new Error(\n        `Cannot insert array into non-array parent type: ${parent.type}`,\n      );\n    }\n    // $FlowExpectedError[prop-missing]\n    parent[replacementParent.key] = nodeToReplaceWith;\n  }\n}\n\n/**\n * Remove a node from the AST its connected to (via the parent pointer).\n */\nexport function removeNodeOnParent(\n  originalNode: ESNode,\n  originalNodeParent: ESNode,\n  visitorKeys?: ?VisitorKeysType,\n): void {\n  const replacementParent = getParentKey(\n    originalNode,","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/packages/flow-parser/oxidized-src/transform/astNodeMutationHelpers.js#L87-L123","documentation":"replaceNodeOnParent accepts either a single node or an array of nodes, but an array is only valid when the located parent slot is itself an array property (replacementParent.type === 'array'). Replacing a single-node slot (e.g. `argument`, `body`, `init`) with multiple nodes has no valid representation, so it throws naming the parent type.","triggerScenarios":"Calling replaceNodeOnParent(node, [a, b]) where node sits in a single-node position such as an expression's argument, a declaration's init, or a function's id — anywhere the visitor key holds one node rather than an array.","commonSituations":"Codemods that expand one statement/expression into several (e.g. splitting an expression into multiple statements) without moving to a statement-list slot; generic 'replace with list' helpers applied to arbitrary nodes.","solutions":["Insert multiple nodes into an array slot instead: find the enclosing array (e.g. program/body or block.body) and use the array-based mutation path with the correct index.","If you must keep the slot, wrap the multiple nodes in a single container node (e.g. a SequenceExpression or a Block) as appropriate for the grammar.","Pass a single node when the target slot is single-valued."],"exampleFix":"// before\nreplaceNodeOnParent(stmt, [decl, call]); // stmt sits in body[i] via single key -> throws\n\n// after\nconst body = program.body;\nconst idx = body.indexOf(stmt);\nreplaceInArray(body, idx, [decl, call]); // array slot supports multiple nodes","handlingStrategy":"validation","validationCode":"// Verify the target slot is an array before replacing with many nodes\nfunction canReplaceWithMany(target) {\n  const parent = target.parent;\n  return Object.keys(parent).some((k) => Array.isArray(parent[k]) && parent[k].includes(target));\n}","typeGuard":"function isInArraySlot(target) {\n  const parent = target.parent;\n  if (parent == null) return false;\n  return Object.keys(parent).some((k) => Array.isArray(parent[k]) && parent[k].includes(target));\n}","tryCatchPattern":null,"preventionTips":["Only pass arrays to replaceNodeOnParent when the node lives in an array property (body, params, arguments).","For single-node slots, replace with one node or restructure the enclosing array."],"tags":["flow","parser","ast","mutation","type-mismatch"],"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"}