{"record":{"id":"ab266343c4f0f71c","repo":"facebook/flow","slug":"simpletransform-invalid-array-result-for-root-nod","errorCode":null,"errorMessage":"SimpleTransform: invalid array result for root node","messagePattern":"SimpleTransform: invalid array result for root node","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/flow-parser/oxidized-src/transform/SimpleTransform.js","lineNumber":103,"sourceCode":"            setParentPointer(resultNode, parent);\n\n            if (Array.isArray(resultNode)) {\n              traversedResultNode = resultNode\n                .map(item => this.transform(item, options))\n                .filter(item => item != null);\n            } else {\n              traversedResultNode = this.transform(resultNode, options);\n            }\n          }\n\n          if (parent == null) {\n            if (node !== rootNode) {\n              throw new Error(\n                'SimpleTransform infra error: Parent not set on non root node, this should not be possible',\n              );\n            }\n            if (Array.isArray(traversedResultNode)) {\n              throw new Error(\n                'SimpleTransform: invalid array result for root node',\n              );\n            } else {\n              resultRootNode = traversedResultNode;\n            }\n          } else if (traversedResultNode == null) {\n            removeNodeOnParent(node, parent, options.visitorKeys);\n          } else {\n            replaceNodeOnParent(\n              node,\n              parent,\n              traversedResultNode,\n              options.visitorKeys,\n            );\n            setParentPointer(traversedResultNode, parent);\n          }\n\n          throw SimpleTraverser.Skip;","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/packages/flow-parser/oxidized-src/transform/SimpleTransform.js#L85-L121","documentation":"SimpleTransform walks the AST and, when it reaches the rootNode with no parent, must assign exactly one node as the transformed root. If the visitor's result for the root node is an array (multiple replacement nodes), there is nowhere to splice them — a Program root cannot be replaced by several nodes — so it throws this invariant error.","triggerScenarios":"Calling SimpleTransform.transform(program, {transform}) where the transform callback returns an array for the Program node itself (or for whatever node you passed as root). Returning arrays is legal only for nodes whose parent slot is an array (e.g. statements inside body).","commonSituations":"Custom transforms designed to expand one statement into several that accidentally also fire on the root; copy-pasted visitors from array-mutation helpers; passing a non-Program root and returning multiple nodes for it.","solutions":["Special-case the root in your visitor: if (node.type === 'Program') return programWithNewBody(node, nodes) — a single Program node containing the changes.","Return a single replacement node for the root; never an array.","Do multi-node insertion into an array slot (e.g. node.body of the Program) instead of replacing the root."],"exampleFix":"// before\ntransform(node) {\n  if (node.type === 'Program') return node.body.map(f); // array for root -> throws\n}\n\n// after\ntransform(node) {\n  if (node.type === 'Program') return SimpleTransform.nodeWith(node, {body: node.body.map(f)});\n}","handlingStrategy":"validation","validationCode":"// Guard the root in your visitor before running the transform\nfunction rootSafeTransform(program, transform) {\n  return SimpleTransform.transformProgram(program, {\n    transform(node) {\n      const result = transform(node);\n      if (node.type === 'Program' && Array.isArray(result)) {\n        throw new TypeError('visitor returned multiple nodes for Program root');\n      }\n      return result;\n    },\n  });\n}","typeGuard":"function isSingleNode(v) {\n  return v != null && typeof v === 'object' && typeof v.type === 'string' && !Array.isArray(v);\n}","tryCatchPattern":null,"preventionTips":["Always special-case Program in visitors that may return arrays.","Put multi-node results into array slots like Program.body, never at the root."],"tags":["flow","parser","ast","transform","simpletransform"],"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-23T08:17:48.524Z"}