leptos-rs/leptos · error
no shared context
Error message
no shared context
What it means
During SSR streaming of a Suspense component (to_html_async_with_buf), when a local resource resolves and the chunk must be marked incomplete, leptos fetches the global shared reactive context via Owner::current_shared_context().expect(...). The panic means serialization was invoked with no shared context installed — i.e. to_html/render-to-string was called without leptos' reactive runtime being set up.
Source
Thrown at leptos/src/suspense_component.rs:451
let mut fut = Box::pin(ScopedFuture::new(ErrorHookFuture::new(
async move {
// race the local resource notifier against the set of tasks
//
// if there are local resources, we just return the fallback immediately
//
// otherwise, we want to wait for resources to load before trying to resolve the body
//
// this is *less efficient* than just resolving the body
// however, it means that you can use reactive accesses to resources/async derived
// inside component props, at any level, and have those picked up by Suspense, and
// that it will wait for those to resolve
select! {
// if there are local resources, bail
// this will only have fired by this point for local resources accessed
// *synchronously*
_ = local_rx => {
let sc = Owner::current_shared_context().expect("no shared context");
sc.set_incomplete_chunk(self.id);
if let Some(tx) =
notify_error_boundary.write_value().take()
{
let _ = tx.send(());
}
None
}
_ = tasks_rx => {
let children = {
let mut children_lock = children.lock().or_poisoned();
children_lock.take().expect("children should not be removed until we render here")
};
// if we ran this earlier, reactive reads would always be registered as None
// this is fine in the case where we want to use Suspend and .await on some future
// but in situations like a <For each=|| some_resource.snapshot()/> we actually
// want to be able to 1) synchronously read a resource's value, but still 2) waitView on GitHub (pinned to 32d20f6c9d)
Solutions
- Use leptos' official server-rendering APIs (leptos_axum::render_route / render_to_string etc.) which install the shared context.
- If serializing manually, create the runtime first (e.g. create_scope + Owner::with, or leptos' to_html entry points that set it up).
- In tests, wrap serialization in run_scope/with the shared context created by leptos helpers.
- Check you haven't spawned the serialization into a task that lost the owner; enter the owner inside the task.
Example fix
// before
let html = suspense.to_html_async_with_buf(...); // no shared context
// after
let html = leptos::ssr::render_to_string(|cx| view! { cx, <Suspense>...</Suspense> }).await;
Defensive patterns
Strategy: validation
Validate before calling
// before custom SSR serialization, ensure the shared context exists assert!(leptos::Owner::current_shared_context().is_some(), "run inside leptos SSR entry points");
Type guard
fn shared_context_ready() -> bool {
leptos::Owner::current_shared_context().is_some()
}
Prevention
- Use leptos_axum / leptos_actix official render entry points
- Never call internal to_html helpers from a bare task without an owner
- In tests, serialize within run_scope
When it happens
Trigger: Calling to_html_async_with_buf (or a Suspense's HTML serializer) manually outside leptos' runtime setup; custom server integration that skips the owner/context initialization; using render helpers outside an act of set_global context.
Common situations: Custom axum/actix integrations not going through leptos' official server rendering entry points; tests that serialize Suspense views without creating a runtime; library code reusing the internal serializer in a fresh task.
Related errors
- children should not be removed until we render here
- Reading from a LocalResource outside Suspense in `ssr` mode
- You cannot use Suspend on an attribute outside Suspense
- You cannot use Suspend on an attribute outside Suspense
- internal error: entered unreachable code
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/5f64f9cb7cae8e01.
Report an issue: GitHub.