leptos-rs/leptos · critical
Executor::spawn_local called, but no global 'spawn_local' fu
Error message
Executor::spawn_local called, but no global 'spawn_local' function is configured.
What it means
This panic is the release-mode (or non-tracing) counterpart for spawn_local: any_spawner has no global 'spawn_local' implementation registered, so the no_op_spawn_local placeholder is invoked and panics. It means local (same-thread) task spawning was requested before an executor was configured.
Source
Thrown at any_spawner/src/lib.rs:88
without threading?)."
);
}
// Wasm panics if you spawn without an executor
#[cfg(feature = "wasm-bindgen")]
#[cold]
#[inline(never)]
fn no_op_spawn(_: PinnedFuture<()>) {
panic!(
"Executor::spawn called, but no global 'spawn' function is configured."
);
}
#[cfg(not(debug_assertions))]
#[cold]
#[inline(never)]
fn no_op_spawn_local(_: PinnedLocalFuture<()>) {
panic!(
"Executor::spawn_local called, but no global 'spawn_local' function \
is configured."
);
}
/// Errors that can occur when using the executor.
#[derive(Error, Debug)]
pub enum ExecutorError {
/// The executor has already been set.
#[error("Global executor has already been set.")]
AlreadySet,
}
/// A global async executor that can spawn tasks.
pub struct Executor;
impl Executor {
/// Spawns a thread-safe [`Future`].View on GitHub (pinned to 32d20f6c9d)
Solutions
- Register a global local executor via any_spawner::spawn_local::set_executor(...) (e.g. LocalSet on native, wasm-bindgen on wasm) at startup, before spawning.
- In Leptos, verify the platform init ran (client hydration or server bootstrap) which wires up the executor.
- Confirm you call spawn_local only from the thread that owns the registered LocalSet/executor.
Example fix
// before
let rt = tokio::runtime::Runtime::new().unwrap();
Executor::spawn_local(async { do_work().await }); // panics: no local executor
// after
let local = tokio::task::LocalSet::new();
any_spawner::spawn_local::set_executor(any_spawner::LocalExecutor::TokioLocalSet(local.clone()));
local.spawn_local(async { do_work().await }); Defensive patterns
Strategy: validation
Validate before calling
// idempotent local-executor installation before any spawn_local
fn ensure_local_executor() {
thread_local! { static INIT: std::cell::Cell<bool> = const { std::cell::Cell::new(false) }; }
INIT.with(|i| {
if !i.get() {
// install appropriate LocalSet/wasm executor here
i.set(true);
}
});
} Prevention
- Pair every Executor::spawn_local usage with a verified executor install on the same thread.
- Prefer wrapping spawn_local in a helper that guarantees initialization.
- Check debug and release builds both init the executor (cfg differences matter).
When it happens
Trigger: Calling Executor::spawn_local in a build without a configured global spawn_local function (no any_spawner::spawn_local::set_executor call), e.g. on native or in release builds where the debug handler is compiled out.
Common situations: Using spawn_local for DOM-touching tasks in wasm without executor init; native apps spawning thread-local futures without a LocalSet-based executor registered; debug vs release differences hiding the richer debug message.
Related errors
- Executor::spawn called, but no global 'spawn' function is co
- At {caller}, tried to spawn a Future with Executor::spawn_lo
- At {caller}, tried to spawn a Future with Executor::spawn()
- internal error: entered unreachable code
- failed to spawn local future
AI-assisted analysis of leptos-rs/leptos@32d20f6c9d (2026-09-01).
Data as JSON: /api/errors/ec121043265ed586.
Report an issue: GitHub.