{"record":{"id":"0421b5e7910ba4d7","repo":"can1357/oh-my-pi","slug":"the-reference-node-is-not-a-child-of-this-node","errorCode":null,"errorMessage":"The reference node is not a child of this node","messagePattern":"The reference node is not a child of this node","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/utils/src/dom/core.ts","lineNumber":213,"sourceCode":"\tappendChild<T extends Node>(child: T): T {\n\t\tconst node: Node = child;\n\t\tif (node === this || node.contains(this)) throw new Error(\"The new child is an ancestor of this node\");\n\t\tif (child instanceof DocumentFragment) {\n\t\t\tfor (const nested of [...child.childNodes]) this.appendChild(nested);\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.push(child);\n\t\treturn child;\n\t}\n\n\t/** Insert a node before a current child, or append for null. */\n\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;","sourceCodeStart":195,"sourceCodeEnd":231,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/utils/src/dom/core.ts#L195-L231","documentation":"Node.insertBefore requires the `reference` node to be a direct child of the node it is called on; it locates reference via `this.childNodes.indexOf(reference)` and throws when the index is -1. Passing null is allowed and delegates to appendChild. Like the standard DOM, this guards against inserting relative to a node that isn't actually a sibling-position marker on this parent.","triggerScenarios":"Calling `parent.insertBefore(child, ref)` where `ref` is not currently a direct child of `parent` — e.g. ref was already removed, belongs to a different parent, or parent/ref were swapped; also via replaceChild (which uses insertBefore internally) and prepend wrappers.","commonSituations":"Holding a stale reference after the reference node was removed or moved elsewhere; inserting into a different parent than owns the marker node; passing an element from a detached copy while the live tree's counterpart is expected; iteration that removes nodes while using one as the insertion point.","solutions":["Assert `ref.parentNode === parent` before calling insertBefore; if false, you have the wrong parent or a stale reference.","If the reference node may have been removed, re-look it up (or use appendChild when no position marker is needed).","Pass `null` as reference when you simply want to append at the end.","When moving nodes between parents, insert into the node's actual `parentNode` rather than a captured parent variable."],"exampleFix":"// before: ref belongs to another parent\notherParent.insertBefore(newChild, marker); // throws: marker is not otherParent's child\n\n// after: use the marker's actual parent, or null to append\n(marker.parentNode ?? parent).insertBefore(newChild, marker.parentNode === parent ? marker : null);","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isDirectChild(parent: Node, node: Node): node is Node & { parentNode: Node } {\n  return parent.childNodes.includes(node);\n}\n// call before: if (isDirectChild(parent, ref)) parent.insertBefore(child, ref); else parent.appendChild(child);","tryCatchPattern":"try {\n  parent.insertBefore(child, ref);\n} catch (err) {\n  if (err instanceof Error && err.message === \"The reference node is not a child of this node\") {\n    parent.appendChild(child); // fallback: append at end\n  } else {\n    throw err;\n  }\n}","preventionTips":["Check `ref.parentNode === parent` before using ref as an insertion marker.","Pass null when position doesn't matter — null delegates to appendChild.","Re-acquire reference nodes after any removal/mutation; don't cache them across tree updates."],"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"}