slint-ui/slint · error
context shouldn't have been set before
Error message
context shouldn't have been set before
What it means
`WindowInner::set_context` stores the `SlintContext` in a `OnceCell`-like cell and panics if the context was already set. The context must be initialized exactly once before any other window function uses it. A double initialization means two runtime instances are driving the same window machinery.
Solutions
- Initialize the Slint context/platform only once per process (guard with std::sync::Once)
- Ensure only one copy/version of the slint crate is linked (check `cargo tree -d`)
- If writing backend code, check `self.ctx.get().is_some()` before calling set_context
- Do not call set_context manually unless implementing a custom backend/platform
Example fix
// before set_context(ctx); set_context(ctx); // panics // after static INIT: std::sync::Once = std::sync::Once::new(); INIT.call_once(|| set_context(ctx));
Defensive patterns
Strategy: validation
Validate before calling
static INIT: std::sync::Once = std::sync::Once::new();
INIT.call_once(|| slint::platform::set_platform(...).expect("platform init")); Type guard
fn context_is_unset(w: &slint::WindowInner) -> bool { w.ctx.get().is_none() } Prevention
- Initialize the Slint platform/context exactly once with std::sync::Once
- Check cargo tree -d for duplicate slint crate copies
- Do not call internal set_context outside custom backend code
When it happens
Trigger: Calling `set_context` twice on the same window, or creating/initializing a component after the context was already installed (e.g. two `slint::Platform`/runtime initializations in the same process).
Common situations: Embedding Slint twice in one process (two independent Slint init calls); mixing static-library copies of slint; custom backend code calling set_context manually; test harnesses that re-initialize the platform per test.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- unable to show popup window
- Popup component is a Window item
- window_adapter just initialized above
- a setter belongs to a field
- an identifier
AI-assisted analysis of slint-ui/slint@3a7e700487 (2026-09-16).
Data as JSON: /api/errors/7b8b4b107d54d8e5.
Report an issue: GitHub.
Appendix: source
Thrown at internal/core/window.rs:2509
self.ctx
.get_or_init(|| crate::context::GLOBAL_CONTEXT.with(|ctx| ctx.get().unwrap().clone()))
}
/// Like [`Self::context`], but returns `None` instead of panicking when no context is
/// available yet.
pub fn try_context(&self) -> Option<&crate::SlintContext> {
if self.ctx.get().is_none()
&& let Some(ctx) = crate::context::GLOBAL_CONTEXT.with(|ctx| ctx.get().cloned())
{
let _ = self.ctx.set(ctx);
}
self.ctx.get()
}
/// Set the SlintContext.
/// This needs to be called once before any other functions that would use the context.
pub fn set_context(&self, ctx: crate::SlintContext) {
self.ctx.set(ctx).map_err(|_| ()).expect("context shouldn't have been set before")
}
}
/// Internal alias for `Rc<dyn WindowAdapter>`.
pub type WindowAdapterRc = Rc<dyn WindowAdapter>;
/// Resolve the [`crate::SlintContext`] associated with a component root by
/// asking it for (or creating) its window adapter and reading the context off
/// the resulting window. Returns `None` only when no adapter can be produced.
pub fn context_for_root(root: &ItemTreeRc) -> Option<crate::SlintContext> {
let comp_ref_pin = vtable::VRc::borrow_pin(root);
let mut adapter = None;
comp_ref_pin.as_ref().window_adapter(true, &mut adapter);
adapter.map(|a| WindowInner::from_pub(a.window()).context().clone())
}
/// Runtime entry point for `BuiltinFunction::AccentColor`. Returns the accent color
/// from the component's [`crate::SlintContext`] reached via its window adapter, orView on GitHub (pinned to 3a7e700487)