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
- Hard-reload to reset DOM state, then re-save the file so a single clean patch batch applies.
- Avoid editing multiple structural aspects of the same subtree in one save; split changes across reloads.
- Check the logged node.Path against the rebuilt children structure to see which index diverged.
- 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
- Filter undefined results of fromReplacementNode before DOM insertion.
- Hard-reload after reordering/duplicating large view sections.
- Do not batch multiple structural edits to the same component in one save.
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
- InsertChildAfter could not build children.
- [HOT RELOADING] Unmatched action
- [HOT RELOADING] Building children, encountered
- [HOT RELOADING] Child at
- {location:?} expected context of type {type_name:?} to be pr
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/064719146442601d.
Report an issue: GitHub.