embassy-rs/embassy · error
InterruptExecutor::spawner() called on uninitialized…
Error message
InterruptExecutor::spawner() called on uninitialized executor.
What it means
Panic from the aarch32 InterruptExecutor::spawner guard: spawner() dereferences executor state that only exists after start() has written it and enabled the SGI. Called before start(), the underlying MaybeUninit slot is uninitialized, so reading it would be undefined behavior; the guard turns that into a deterministic panic. Fires when a task or driver requests a SendSpawner from an executor that was never started, or in the wrong order (spawner() before start() during init).
Solutions
- Ensure start() is called on the executor before any code obtains its SendSpawner
- Get the spawner from inside tasks via Spawner::for_current_executor() rather than holding one from before start
- Reorder initialization so executor startup precedes task creation code that uses spawner()
- Add an init-order unit test or assertion in board setup to catch the wrong ordering early
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at embassy-executor/src/platform/aarch32.rs:295 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of embassy-rs/embassy@463a07b963 (2026-09-10).
Data as JSON: /api/errors/7f209c16580cb7f9.
Report an issue: GitHub.
Appendix: source
Thrown at embassy-executor/src/platform/aarch32.rs:295
(&raw mut (*inner).executor).write(raw::Executor::new(target as *mut ()));
&*inner
};
inner.target.enable();
inner.executor.spawner().make_send()
}
/// Get a SendSpawner for this executor
///
/// This returns a [`SendSpawner`](crate::SendSpawner) you can use to spawn tasks on this
/// executor.
///
/// This MUST only be called on an executor that has already been started.
/// The function will panic otherwise.
pub fn spawner(&'static self) -> crate::SendSpawner {
if !critical_section::with(|cs| self.started.borrow(cs).get()) {
panic!("InterruptExecutor::spawner() called on uninitialized executor.");
}
let inner = unsafe { (&*self.inner.get()).assume_init_ref() };
inner.executor.spawner().make_send()
}
}
}
View on GitHub (pinned to 463a07b963)