yewstack/yew · error
a resuming component must have a Suspense ancestor
Error message
a resuming component must have a Suspense ancestor
What it means
When a previously suspended component resumes and commits its render, Yew looks up its BaseSuspense ancestor again to hand over the pending rendered callback (BaseSuspense::defer_rendered). This expect fires when that ancestor is gone: the suspension was created under a <Suspense> that has since been unmounted, re-keyed, or re-created while the child was still suspended. It is an internal-consistency panic - the boundary that accepted the suspension is expected to still exist at resume time.
Source
Thrown at packages/yew/src/html/component/lifecycle.rs:523
let new_node_ref =
bundle.reconcile(root, &scope, parent, sibling_slot.to_position(), new_vdom);
own_slot.reassign(new_node_ref);
let first_render = !self.has_rendered;
self.has_rendered = true;
if resuming_from_suspension {
// The DOM we just reconciled still lives in the ancestor
// Suspense's detached parent. The Suspense must process
// the Resume message and re-render to shift children into
// the live tree before our effects observe the DOM.
// Hand the pending `rendered` to the Suspense; it will
// re-schedule it once it fully un-suspends.
let pending = PendingRendered::new(shared_state.clone(), first_render);
let suspense_scope = scope
.find_parent_scope::<BaseSuspense>()
.expect("a resuming component must have a Suspense ancestor");
BaseSuspense::defer_rendered(&suspense_scope, self.comp_id, pending);
} else {
scheduler::push_component_rendered(
self.comp_id,
Box::new(RenderedRunner {
state: shared_state.clone(),
first_render,
}),
first_render,
);
}
}
#[cfg(feature = "hydration")]
ComponentRenderState::Hydration {
ref mut fragment,
ref parent,
ref mut own_slot,View on GitHub (pinned to 0e4a05472f)
Solutions
- Hoist the <Suspense> boundary above the conditional or router switch so it stays mounted while any child can suspend
- Do not key or conditionally remount the boundary itself
- Upgrade to the newest Yew patch release - suspense resume handling has received fixes
- If it still reproduces on the latest version, file an issue with a minimal repro (suspension triggered while the boundary unmounts)
Example fix
// before: boundary is swapped out with the route while children still suspend
html! { <Route>{ route_view }</Route> } // <Suspense> lives inside route_view
// after: boundary outlives the switch
html! {
<Suspense fallback={fallback()}>
<Route>{ route_view }</Route>
</Suspense>
} Defensive patterns
Strategy: validation
Prevention
- Hoist <Suspense> above route switches and conditionals so it stays mounted while children suspend
- Never key or conditionally remount a Suspense boundary that has pending children
- Stay on the latest Yew patch release; resume handling has been fixed over time
When it happens
Trigger: Unmounting, re-keying, or conditionally removing the <Suspense> subtree while a child is still suspended (route change mid-load, a toggle flipping the boundary off); re-parenting the suspended component so its scope chain no longer reaches the original boundary.
Common situations: Router-driven page swaps where the boundary lives inside the swapped page; show.then(|| html!{<Suspense>...</Suspense>}) toggled during an async load; upgrading across Yew versions where suspense resume handling had bugs.
Related errors
- To suspend rendering, a <Suspense /> component is required.
- failed to create detached element
- couldn't clone cached element
- couldn't clone node to be cached
- failed to remove child element
AI-assisted analysis of yewstack/yew@0e4a05472f (2026-08-22).
Data as JSON: /api/errors/907e75e14d55e49e.
Report an issue: GitHub.