facebook/lexical · error
${error.toString()} Parent: ${dom.tagName}, new child: {tag:
Error message
${error.toString()} Parent: ${dom.tagName}, new child: {tag: ${replacementDOM.tagName} key: ${nextFirstChildKey}}, old child: {tag: ${lastDOM.tagName}, key: ${prevFirstChildKey}}. What it means
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.
Source
Thrown at packages/lexical/src/LexicalReconciler.ts:1618
try {
if (lastDOM.parentNode === dom) {
dom.replaceChild(replacementDOM, lastDOM);
} else {
// lastDOM was reused as a descendant of replacementDOM (cross-parent
// move, e.g. wrapping an image in a link). It's already detached
// from `dom`, so just insert the replacement.
slot.insertChild(replacementDOM);
}
} catch (error) {
if (typeof error === 'object' && error != null) {
const msg = `${error.toString()} Parent: ${
dom.tagName
}, new child: {tag: ${
replacementDOM.tagName
} key: ${nextFirstChildKey}}, old child: {tag: ${
lastDOM.tagName
}, key: ${prevFirstChildKey}}.`;
throw new Error(msg);
} else {
throw error;
}
}
$destroyNode(prevFirstChildKey, null);
}
const nextChildNode = activeNextNodeMap.get(nextFirstChildKey);
if ($isTextNode(nextChildNode)) {
if (subTreeTextFormat === null) {
subTreeTextFormat = nextChildNode.getFormat();
subTreeTextStyle = nextChildNode.getStyle();
subTreeFirstTextKey = nextChildNode.__key;
}
}
} else {
const prevChildren = $createChildrenArray(prevElement, activePrevNodeMap);
const nextChildren = $createChildrenArray(nextElement, activeNextNodeMap);
invariant(View on GitHub (pinned to 76a22dcba9)
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.
Example fix
// before (external mutation)
document.querySelector('[data-lexical-key="12"]').remove();
// after
editor.update(() => {
$getNodeByKey('12').remove();
}); Defensive patterns
Strategy: try-catch
Validate before calling
null
Type guard
null
Try / catch
try {
editor.update(() => applyChanges());
} catch (e) {
if (e instanceof Error && e.message.includes('Parent:') && e.message.includes('old child:')) {
console.error('Reconciliation mismatch (likely external DOM mutation):', e.message);
editor.dispatchCommand(CLEAR_EDITOR_COMMAND, undefined); // recover
} else { throw e; }
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- ${method} is not supported in headless mode
- Internal Lexical error: invariant() called without a message
- Cell not found at cords.
AI-assisted analysis of facebook/lexical@76a22dcba9 (2026-08-31).
Data as JSON: /api/errors/8200c1ae7cdba242.
Report an issue: GitHub.