{"record":{"id":"8200c1ae7cdba242","repo":"facebook/lexical","slug":"error-tostring-parent-dom-tagname-new-ch","errorCode":null,"errorMessage":"${error.toString()} Parent: ${dom.tagName}, new child: {tag: ${replacementDOM.tagName} key: ${nextFirstChildKey}}, old child: {tag: ${lastDOM.tagName}, key: ${prevFirstChildKey}}.","messagePattern":"(.+?) Parent: (.+?), new child: (.+?), old child: (.+?)\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/lexical/src/LexicalReconciler.ts","lineNumber":1618,"sourceCode":"      try {\n        if (lastDOM.parentNode === dom) {\n          dom.replaceChild(replacementDOM, lastDOM);\n        } else {\n          // lastDOM was reused as a descendant of replacementDOM (cross-parent\n          // move, e.g. wrapping an image in a link). It's already detached\n          // from `dom`, so just insert the replacement.\n          slot.insertChild(replacementDOM);\n        }\n      } catch (error) {\n        if (typeof error === 'object' && error != null) {\n          const msg = `${error.toString()} Parent: ${\n            dom.tagName\n          }, new child: {tag: ${\n            replacementDOM.tagName\n          } key: ${nextFirstChildKey}}, old child: {tag: ${\n            lastDOM.tagName\n          }, key: ${prevFirstChildKey}}.`;\n          throw new Error(msg);\n        } else {\n          throw error;\n        }\n      }\n      $destroyNode(prevFirstChildKey, null);\n    }\n    const nextChildNode = activeNextNodeMap.get(nextFirstChildKey);\n    if ($isTextNode(nextChildNode)) {\n      if (subTreeTextFormat === null) {\n        subTreeTextFormat = nextChildNode.getFormat();\n        subTreeTextStyle = nextChildNode.getStyle();\n        subTreeFirstTextKey = nextChildNode.__key;\n      }\n    }\n  } else {\n    const prevChildren = $createChildrenArray(prevElement, activePrevNodeMap);\n    const nextChildren = $createChildrenArray(nextElement, activeNextNodeMap);\n    invariant(","sourceCodeStart":1600,"sourceCodeEnd":1636,"githubUrl":"https://github.com/facebook/lexical/blob/76a22dcba981b46119fcec45f935270707e26a57/packages/lexical/src/LexicalReconciler.ts#L1600-L1636","documentation":"During DOM reconciliation, Lexical catches an error thrown while replacing a child element and rethrows it enriched with context: the parent tag, the new child's tag and key, and the old child's tag and key. The embedded ${error.toString()} is the original reconciler failure; the wrapper exists to make the offending DOM nodes diagnosable.","triggerScenarios":"An error occurs in LexicalReconciler while replacing a first child during updateDomCreation/updateChildrenWithV2 logic — the caught `error` at line ~1618 is wrapped when a replacement DOM (replacementDOM) does not line up with the last DOM (lastDOM) being destroyed.","commonSituations":"Browser extensions mutating the editor DOM; external code directly manipulating the editor's DOM nodes; bugs in custom node updateDOM/exportDOM implementations; reconciliation races with scripts removing elements.","solutions":["Read the inner error.toString() in the message first — it is the root cause.","Remove browser extensions or scripts that mutate the editor's DOM from outside Lexical APIs.","Audit custom nodes' updateDOM/createDOM for incorrect tag reuse or mutation.","Reproduce in development mode where Lexical runs with full warnings and more validation to get a clearer stack."],"exampleFix":"// before (external mutation)\ndocument.querySelector('[data-lexical-key=\"12\"]').remove();\n// after\neditor.update(() => {\n  $getNodeByKey('12').remove();\n});","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"try {\n  editor.update(() => applyChanges());\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Parent:') && e.message.includes('old child:')) {\n    console.error('Reconciliation mismatch (likely external DOM mutation):', e.message);\n    editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined); // recover\n  } else { throw e; }\n}","preventionTips":["Never mutate the editor DOM outside Lexical APIs.","Test with browser extensions disabled or in incognito.","Audit custom node createDOM/updateDOM for tag correctness.","Reproduce issues in dev mode for clearer errors."],"tags":["dom","reconciliation","internal-error"],"backgroundTag":"dom-reconciliation-mismatch","analyzedSha":"76a22dcba981b46119fcec45f935270707e26a57","analyzedAt":"2026-08-31T21:45:54.792Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}