DioxusLabs/dioxus · error
Lazy value is not initialized. Make sure to call `initialize
Error message
Lazy value is not initialized. Make sure to call `initialize` before dereferencing.
What it means
Lazy is a OnceLock-based global used by dioxus-fullstack for server values. A Lazy created with Lazy::lazy()/Default has no constructor, so get()/Deref requires that set()/try_set() was called first; when the constructor is None and the value was never set, this expect panics. Lazy values with constructors self-initialize on first access, but bare lazy() values do not.
Source
Thrown at packages/fullstack/src/lazy.rs:98
if self
.started_initialization
.swap(true, std::sync::atomic::Ordering::SeqCst)
{
self.value.wait();
return Ok(());
}
// Otherwise, we need to initialize the value
self.set(constructor().unwrap())?;
}
Ok(())
}
/// Get a reference to the value of the `Lazy` instance. This will block the current thread if the
/// value is not yet initialized.
pub fn get(&self) -> &T {
if self.constructor.is_none() {
return self.value.get().expect("Lazy value is not initialized. Make sure to call `initialize` before dereferencing.");
};
if self.value.get().is_none() {
self.initialize().expect("Failed to initialize lazy value");
}
self.value.get().unwrap()
}
}
impl<T: Send + Sync + 'static> Default for Lazy<T> {
fn default() -> Self {
Self::lazy()
}
}
impl<T: Send + Sync + 'static> std::ops::Deref for Lazy<T> {
type Target = T;View on GitHub (pinned to 393d190a80)
Solutions
- Initialize the Lazy during server setup: lazy.set(value) or try_set(value) before any access
- Create it with Lazy::new(constructor) instead of Lazy::lazy() so it self-initializes on first get()
- Only deref the Lazy inside a running dioxus::serve app where setup guarantees initialization
- In tests, call set()/initialize() in the harness before touching code that dereferences it
Example fix
// before
static DB: Lazy<Db> = Lazy::lazy();
fn handler() { DB.query(...); } // panics: never set
// after
static DB: Lazy<Db> = Lazy::new(|| async { connect().await });
// or: DB.set(connect_now()) during dioxus::serve setup Defensive patterns
Strategy: validation
Validate before calling
// Expose an accessor instead of raw deref:
pub fn db() -> Option<&'static Db> {
DB.try_get()
}
// or ensure setup ran:
fn ensure_initialized(lazy: &Lazy<Db>) -> Result<(), CapturedError> { lazy.initialize() } Prevention
- Prefer Lazy::new(constructor) over Lazy::lazy() so values self-initialize
- Centralize set()/try_set() in one server setup function called by dioxus::serve
- In tests, always run the serve setup (or call initialize()) before touching Lazy globals
- Wrap Lazy access in an Option-returning helper instead of bare deref
When it happens
Trigger: Dereferencing a Lazy created via Lazy::lazy() that was never initialized: accessing a fullstack server context or a Lazy global (e.g. a connection pool) outside of the dioxus::serve setup that should call set(), or forgetting the initialization step in the server config callback.
Common situations: Unit tests calling server helpers that deref a Lazy without booting the server; a binary path that never runs launch setup; refactoring that moves set() behind a disabled feature or config branch.
Related errors
- Failed to parse index.html from public directory
- Failed to read index.html from public directory
- Failed to create new router after hot-patch!
- Failed to serialize SSE event
- protocols is an invalid header value
AI-assisted analysis of DioxusLabs/dioxus@393d190a80 (2026-08-16).
Data as JSON: /api/errors/5f5fc57edc077b95.
Report an issue: GitHub.