{"record":{"id":"7b07a028994a74ca","repo":"can1357/oh-my-pi","slug":"the-node-to-replace-is-not-a-child-of-this-node","errorCode":null,"errorMessage":"The node to replace is not a child of this node","messagePattern":"The node to replace is not a child of this node","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/dom/core.ts","lineNumber":228,"sourceCode":"\tinsertBefore<T extends Node>(child: T, reference: Node | null): T {\n\t\tif (reference === null) return this.appendChild(child);\n\t\tconst index = this.childNodes.indexOf(reference);\n\t\tif (index < 0) throw new Error(\"The reference node is not a child of this node\");\n\t\tif (child instanceof DocumentFragment) {\n\t\t\tfor (const nested of [...child.childNodes]) this.insertBefore(nested, reference);\n\t\t\treturn child;\n\t\t}\n\t\tchild.parentNode?.removeChild(child);\n\t\tchild.parentNode = this;\n\t\tchild.setOwnerDocument(this.documentForCreation());\n\t\tthis.childNodes.splice(index, 0, child);\n\t\treturn child;\n\t}\n\n\t/** Replace a current child with another node. */\n\treplaceChild<T extends Node>(child: Node, previous: T): T {\n\t\tconst index = this.childNodes.indexOf(previous);\n\t\tif (index < 0) throw new Error(\"The node to replace is not a child of this node\");\n\t\tthis.removeChild(previous);\n\t\tthis.insertBefore(child, this.childNodes[index] ?? null);\n\t\treturn previous;\n\t}\n\n\t/** Remove a current child. */\n\tremoveChild<T extends Node>(child: T): T {\n\t\tconst index = this.childNodes.indexOf(child);\n\t\tif (index < 0) throw new Error(\"The node to remove is not a child of this node\");\n\t\tthis.childNodes.splice(index, 1);\n\t\tchild.parentNode = null;\n\t\treturn child;\n\t}\n\n\t/** Replace all children with nodes or strings. */\n\treplaceChildren(...children: Array<Node | string>): void {\n\t\tfor (const child of this.childNodes) child.parentNode = null;\n\t\tthis.childNodes = [];","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/dom/core.ts#L210-L246","documentation":"Node.replaceChild(child, previous) requires `previous` to be an existing direct child of the node; `this.childNodes.indexOf(previous)` returning -1 throws this error before any mutation. This mirrors the standard DOM NotFoundError behavior — you can only replace a node that is actually a child of the receiver.","triggerScenarios":"Calling `parent.replaceChild(newChild, oldChild)` where `oldChild` was already removed, was never a child of `parent`, or belongs to another parent/subtree; calling with swapped arguments so the 'previous' slot holds the new node.","commonSituations":"Replacing a node after a prior removal/move made the reference stale; using a node from a cloned/detached subtree; argument-order mistakes (child vs previous) in code ports from other DOM implementations; batch updates that replace the same node twice.","solutions":["Assert `oldChild.parentNode === parent` before replaceChild; if it's null, the node is already detached.","Check argument order: signature is replaceChild(newChild, oldChild) — the node being replaced goes second.","If the node may already be gone, guard with a membership check or catch and fall back to appendChild/removeChild accordingly.","Re-query the live child (by index or querySelector) instead of reusing a node captured before prior mutations."],"exampleFix":"// before: swapped/invalid previous\nparent.replaceChild(oldChild, newChild); // throws: oldChild is not a child\n\n// after: correct order plus guard\nif (oldChild.parentNode === parent) {\n  parent.replaceChild(newChild, oldChild);\n}","handlingStrategy":"validation","validationCode":"if (oldChild.parentNode === parent) {\n  parent.replaceChild(newChild, oldChild);\n}","typeGuard":"function isReplaceable(parent: Node, oldChild: Node): boolean {\n  return parent.childNodes.includes(oldChild);\n}","tryCatchPattern":"try {\n  parent.replaceChild(newChild, oldChild);\n} catch (err) {\n  if (err instanceof Error && err.message === \"The node to replace is not a child of this node\") {\n    // already detached or wrong parent — decide: append instead or skip\n    parent.appendChild(newChild);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Remember argument order: replaceChild(newChild, oldChild) — the replaced node goes second.","Verify oldChild.parentNode === parent before replacing; stale references after removals are the top cause.","Never reuse nodes from cloned/detached subtrees as replacement targets; re-query the live tree."],"tags":["dom","tree-structure","invalid-argument"],"backgroundTag":"dom-node-not-a-child","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}