leptos-rs/leptos · error
expected context of type to be present
Error message
{location:?} expected context of type {type_name:?} to be present What it means
expect_context<T>() panics when no context value of type T has been provided by any owner in the current reactive ownership tree. Leptos context is provided with provide_context and consumed via use_context/expect_context; use_context returns Option, while expect_context is the assertive variant that assumes the context must exist. This panic means the consumer is running outside the subtree (or owner) where that context was provided.
Solutions
- Wrap the consuming component (or the whole app) in the provider that calls provide_context for the required type (e.g. QueryClientProvider for QuerySignal).
- Replace expect_context with use_context::<T>() and handle the None case gracefully instead of panicking.
- If used in a spawned task, ensure it inherits the correct Owner via Owner::with_current or provide the context explicitly in the task.
- Check that the provider is not behind a conditional (cfg, Suspense fallback, route guard) that can render before it exists.
Example fix
// before
#[component]
fn App() -> impl IntoView {
view! { <Todos/> } // Todos calls query_signal -> panics: no QueryClient context
}
// after
#[component]
fn App() -> impl IntoView {
view! {
<QueryClientProvider client=QueryClient::new()>
<Todos/>
</QueryClientProvider>
}
} Defensive patterns
Strategy: fallback
Validate before calling
if let Some(client) = use_context::<QueryClient>() { /* proceed */ } else { // render default or log before calling expect_context } Type guard
fn has_context<T: Clone + 'static>() -> bool { use_context::<T>().is_some() } Prevention
- Always prefer use_context (Option) over expect_context at component boundaries you do not control.
- Place providers at the top of the app tree, above the router.
- Verify spawned tasks inherit owners via spawn_local / Owner::with_current.
When it happens
Trigger: Calling expect_context::<T>() (directly or indirectly via query_signal_with_options) in a component, signal getter, or closure whose owner was not created inside a component that called provide_context::<T>() — e.g. calling it before the provider mounts, in a root that is not nested under the provider, or in an async task spawned with the wrong Owner.
Common situations: Using QuerySignal (leptos_query) at the app root without wrapping the app in the query client provider; rendering a component both inside and outside the provider (e.g. in a portal or router fallback); spawning a task with tokio::spawn instead of spawn_local, losing the owner; hydration mismatch where the provider is conditionally rendered.
Related errors
- Tried to access a reactive value that has already been…
- At , you call `to_server_error()` or use `server_fn_error!`…
- at , the `sandboxed-arenas` feature is active, but no Arena…
- could not find key for index
- should not be used with nested routes.
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/605f0374e6972c7c.
Report an issue: GitHub.
Appendix: source
Thrown at reactive_graph/src/owner/context.rs:306
/// let value = use_context::<String>()
/// .expect("could not find String in context");
/// assert_eq!(value, "foo");
/// let value2 = use_context::<String>()
/// .expect("could not find String in context");
/// assert_eq!(value2, "foo");
/// });
/// });
/// # });
/// ```
/// ## Panics
/// Panics if a context of this type is not found in the current reactive
/// owner or its ancestors.
#[track_caller]
pub fn expect_context<T: Clone + 'static>() -> T {
let location = std::panic::Location::caller();
use_context().unwrap_or_else(|| {
panic!(
"{:?} expected context of type {:?} to be present",
location,
std::any::type_name::<T>()
)
})
}
/// Extracts a context value of type `T` from the reactive system, and takes ownership,
/// removing it from the context system.
///
/// This traverses the reactive ownership graph, beginning from the current reactive
/// [`Owner`] and iterating through its parents, if any. When the value is found, it is removed,
/// and is not available to any other [`use_context`] or [`take_context`] calls.
///
/// If the value is `Clone`, use [`use_context`] instead.
///
/// The context value should have been provided elsewhere using
/// [`provide_context`](provide_context).View on GitHub (pinned to 32d20f6c9d)