can1357/oh-my-pi · error · Error

This node has no owner document

Error message

This node has no owner document

What it means

Node.documentForCreation returns the owning Document for factory calls (createElement, createTextNode, etc.). It returns `this` when the node is itself a Document, otherwise requires `ownerDocument` to have been set via setOwnerDocument; nodes created outside a document (never passed through setOwnerDocument) have no owner and throw. Internally, child-mutating operations (appendChild, insertBefore, append, prepend, textContent, replaceWith) call this to create text nodes from strings, so the error surfaces there too.

Source

Thrown at packages/utils/src/dom/core.ts:318

		if (other.contains(this)) return 10;
		const root = this.ownerDocument ?? this;
		const nodes: Node[] = [];
		const visit = (node: Node): void => {
			nodes.push(node);
			for (const child of node.childNodes) visit(child);
		};
		visit(root);
		return nodes.indexOf(this) < nodes.indexOf(other) ? 4 : 2;
	}

	setOwnerDocument(document: Document): void {
		if (this.nodeType !== NodeType.DOCUMENT) this.ownerDocument = document;
		for (const child of this.childNodes) child.setOwnerDocument(document);
	}

	documentForCreation(): Document {
		if (this instanceof Document) return this;
		if (!this.ownerDocument) throw new Error("This node has no owner document");
		return this.ownerDocument;
	}
}

/** Text node. */
export class Text extends Node {
	data: string;
	serializeRaw: boolean;

	constructor(data: string, ownerDocument: Document | null = null, serializeRaw = false) {
		super(NodeType.TEXT, "#text", ownerDocument);
		this.data = data;
		this.serializeRaw = serializeRaw;
	}

	/** Number of UTF-16 code units. */
	get length(): number {
		return this.data.length;

View on GitHub (pinned to 9690622007)

Solutions

  1. Create nodes through the document API (document.createElement / createTextNode) so ownerDocument is set automatically.
  2. For standalone-built nodes, call the document's adoption path (setOwnerDocument) — attaching the node to a document tree does this recursively.
  3. Ensure the root of your detached subtree is created by a Document so ownership propagates down to all children.
  4. If rehydrating nodes, re-run setOwnerDocument(document) on the root before mutating it.

Example fix

// before: node built with new, no owner document
const el = new Element("div");
el.textContent = "hi"; // throws: no owner document

// after: create via the document
const el = document.createElement("div");
el.textContent = "hi"; // ok
Defensive patterns

Strategy: validation

Validate before calling

if (!node.ownerDocument && !(node instanceof Document)) {
  node.setOwnerDocument(document); // adopt before mutating
}
node.textContent = "hi"; // safe: owner document now exists

Type guard

function hasOwnerDocument(node: Node): boolean {
  return node instanceof Document || node.ownerDocument != null;
}

Try / catch

try {
  node.appendChild(text);
} catch (err) {
  if (err instanceof Error && err.message === "This node has no owner document") {
    node.setOwnerDocument(document);
    node.appendChild(text); // retry after adoption
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Appending/inserting/prepending a raw string child to a node whose ownerDocument was never assigned — i.e. a node constructed directly with `new Element(...)`/`new Text(...)` rather than via document.createElement and not attached through setOwnerDocument; calling documentForCreation() directly on such a detached node.

Common situations: Constructing DOM nodes with `new` in library/test code and mutating them before passing them through any Document; building a subtree standalone and calling textContent = '...' before adopting it; nodes deserialized/rehydrated without re-running setOwnerDocument.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/45b48d21358678a7. Report an issue: GitHub.