leptos-rs/leptos · warning

[HOT RELOADING] Could not find replacement node at

Error message

[HOT RELOADING] Could not find replacement node at 

What it means

fromReplacementNode received a replacement node described only by a Path (a reference to an existing DOM node being moved) but childAtPath could not resolve that path in the current actualChildren snapshot, so it warns and returns undefined. The caller then inserts/splices `undefined` into the DOM (e.g. append(...[undefined])), which can produce the text 'Undefined' or throw later.

Source

Thrown at leptos_hot_reload/src/patch.js:273

          const range = new Range();
          range.setStartBefore(child.start);
          range.setEndAfter(child.end);
          // okay this is somewhat silly
          // if we do cloneContents() here to return it,
          // we strip away the event listeners
          // if we're moving just one object, this is less than ideal
          // so I'm actually going to *extract* them, then clone and reinsert
          /* const toReinsert = range.cloneContents();
					if (child.end.nextSibling) {
						child.end.parentNode.insertBefore(toReinsert, child.end.nextSibling);
					} else {
						child.end.parentNode.appendChild(toReinsert);
					} */
          childNode = range.cloneContents();
        }
        return childNode;
      } else {
        console.warn(
          "[HOT RELOADING] Could not find replacement node at ",
          node.Path,
        );
        return undefined;
      }
    }
  }

  function buildActualChildren(element, range) {
    const walker = document.createTreeWalker(
      element,
      NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT | NodeFilter.SHOW_COMMENT,
      {
        acceptNode(node) {
          if (
            node.parentNode == element &&
            (!range || range.isPointInRange(node, 0))
          ) {

View on GitHub (pinned to 32d20f6c9d)

Solutions

  1. Hard-reload to reset DOM state, then re-save the file so a single clean patch batch applies.
  2. Avoid editing multiple structural aspects of the same subtree in one save; split changes across reloads.
  3. Check the logged node.Path against the rebuilt children structure to see which index diverged.
  4. Update patch.js so undefined results from fromReplacementNode are filtered before DOM insertion.

Example fix

// before
const newChildren = action.AppendChildren.map((x) => fromReplacementNode(x, actualChildren));
child.node.append(...newChildren);
// after
const newChildren = action.AppendChildren
  .map((x) => fromReplacementNode(x, actualChildren))
  .filter(Boolean);
child.node.append(...newChildren);
Defensive patterns

Strategy: fallback

Type guard

function isResolvedNode(x) {
  return x instanceof Node;
}

Prevention

When it happens

Trigger: A ReplaceWith/AppendChildren/InsertChild patch whose replacement is a {Path: [...]} referencing a node that no longer exists at that index — paths shifted by earlier patches in the same batch, or the path length exceeds the rebuilt children tree.

Common situations: Reordering or duplicating elements in a view during development; chained structural edits in one save; stale DOM after a failed earlier patch in the same batch.

Related errors


AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01). Data as JSON: /api/errors/064719146442601d. Report an issue: GitHub.