leptos-rs/leptos · error
anchor is not a child of the parent
Error message
anchor is not a child of the parent
What it means
MockRenderer::insert_node inserts a child before an anchor by finding the anchor's position in the parent's children list; if the anchor is not among the parent's children, position() returns None and it panics. The mock DOM mirrors real renderer invariants, so this flags bookkeeping drift between parent/anchor tracking.
Source
Thrown at tachys/src/renderer/mock_dom.rs:493
debug_assert!(&parent.0 != new_child);
// remove if already mounted
if let Some(parent) = MockDom::get_parent(new_child) {
let parent = Element(parent);
MockDom::remove_node(&parent, new_child);
}
// mount on new parent
Document::with_node_mut(parent.0 .0, |parent| {
if let NodeType::Element {
ref mut children, ..
} = parent.ty
{
match anchor {
None => children.push(new_child.clone()),
Some(anchor) => {
let anchor_pos = children
.iter()
.position(|item| item.0 == anchor.0)
.expect("anchor is not a child of the parent");
children.insert(anchor_pos, new_child.clone());
}
}
} else {
panic!("parent is not an element");
}
});
// set parent on child node
Document::with_node_mut(new_child.0, |node| {
node.parent = Some(parent.0 .0)
});
}
fn remove_node(
parent: &Self::Element,
child: &Self::Node,
) -> Option<Self::Node> {
let child = Document::with_node_mut(parent.0 .0, |parent| {View on GitHub (pinned to 32d20f6c9d)
Solutions
- Ensure the anchor passed to insert_node is a current child of the same parent node
- Update anchors after moving/removing nodes in the mock DOM before re-inserting
- Re-render or rebuild the mock tree when structural tests mutate children directly
- If testing reconciliation, use the renderer's own move/remove APIs instead of poking the children vec
Example fix
// before mock.insert_node(&mut node, &stale_anchor); // panics // after assert!(parent.children().any(|c| c == stale_anchor)); mock.insert_node(&mut node, &stale_anchor); // anchor verified in parent
Defensive patterns
Strategy: validation
Validate before calling
fn is_child(parent: &MockNode, anchor: &MockNode) -> bool {
parent.children().iter().any(|c| c.id == anchor.id)
}
// call before: assert!(is_child(&parent, &anchor)); Type guard
fn find_anchor_pos(children: &[MockNode], anchor: &MockNode) -> Option<usize> {
children.iter().position(|c| c.id == anchor.id)
} Prevention
- Always insert/move anchors through the renderer's own APIs
- After removing/moving nodes, refresh anchor references before re-use
- In tests, assert the anchor is present in the parent before insert_node
- Avoid cloning anchors between different mock trees
When it happens
Trigger: Calling insert_node with an anchor belonging to a different parent, an anchor already removed from the mock DOM, or stale anchor references after mock-DOM mutations; also implicitly when parent bookkeeping (children vec) diverges from anchor references.
Common situations: Unit/integration tests using the mock DOM renderer with manually manipulated children; view reconciliation code paths that move anchors without updating the parent's child list; cloning anchors across trees in tests.
Related errors
- tried to remove a parentless node
- Executor::spawn called, but no global 'spawn' function is co
- Executor::spawn_local called, but no global 'spawn_local' fu
- At {caller}, tried to spawn a Future with Executor::spawn()
- At {caller}, tried to spawn a Future with Executor::spawn_lo
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/6e038c71d9365c31.
Report an issue: GitHub.