slint-ui/slint · error
spawn is called while the SlintContext is still alive
Error message
spawn is called while the SlintContext is still alive
What it means
`xdg_desktop_settings::spawn()` starts the portal watcher that tracks desktop appearance settings (dark mode etc.). It upgrades the passed `SlintContextWeak`; if the context is already gone the function cannot proceed and panics, since spawn must be called while the context is alive.
Solutions
- Keep the `SlintContext` (platform) alive until after backend startup completes; only drop it at process end
- Ensure `slint::platform::set_platform()` is called before any teardown paths run
- If this occurs during normal shutdown, defer dropping the context until after the event loop exits
Example fix
// before
{
let ctx = slint::platform::Platform::context();
drop(ctx); // context gone
start_backend(); // spawn panics upgrading weak ctx
}
// after
{
let ctx = slint::platform::Platform::context();
start_backend(); // spawn succeeds
// ctx dropped last
} Defensive patterns
Strategy: type-guard
Validate before calling
// ensure the platform context is alive before backend startup let ctx = slint::platform::Platform::context(); // strong reference held backend_start(&ctx);
Try / catch
std::panic::catch_unwind(|| xdg_desktop_settings::spawn(&shared, &ctx_weak))
.map_err(|_| anyhow!("SlintContext dropped before portal watcher spawn"))?; Prevention
- Hold the SlintContext until the process/event loop ends
- Call set_platform before any shutdown paths can run
- Defer dropping the context until after the event loop exits
When it happens
Trigger: Calling `spawn` (from backend startup) after the `SlintContext` was dropped or before it was fully created - i.e. backend shutdown/teardown racing with settings initialization.
Common situations: Dropping the Slint platform/context very early in embedded or custom-platform setups; shutting down the app during initialization; misordered platform creation in custom integrations.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Could not find executable name of the slint-lsp
- the winit event loop runs inside the context that owns this…
- a setter belongs to a field
- an identifier
- binding was of the wrong type
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/5b5b8e1153d8efd2.
Report an issue: GitHub.
Appendix: source
Thrown at internal/backends/winit/xdg_desktop_settings.rs:279
name.as_str(),
"org.freedesktop.DBus.Error.ServiceUnknown"
| "org.freedesktop.DBus.Error.NameHasNoOwner"
),
zbus::Error::FDO(err) => matches!(
**err,
zbus::fdo::Error::ServiceUnknown(_) | zbus::fdo::Error::NameHasNoOwner(_)
),
_ => false,
}
}
/// Starts the portal watcher and the timeout that releases the first windows if
/// the portal is slow or missing. Returns the task so the backend can abort it.
pub(crate) fn spawn(
shared_data: &Rc<SharedBackendData>,
ctx: &SlintContextWeak,
) -> Option<i_slint_core::future::JoinHandle<()>> {
let strong_ctx = ctx.upgrade().expect("spawn is called while the SlintContext is still alive");
// Hold back the first windows until the query applies the real appearance.
shared_data.desktop_settings.appearance_pending.set(true);
let shared_weak = Rc::downgrade(shared_data);
let ctx_weak = ctx.clone();
strong_ctx
.spawn_local(async move {
if let Err(err) = watch(&shared_weak, ctx_weak).await {
if !portal_unavailable(&err) {
i_slint_core::debug_log!("Error watching for xdg desktop settings: {err}");
}
// The portal is unavailable; create the waiting windows anyway.
finish_appearance_query(&shared_weak);
}
})
.ok()
}
View on GitHub (pinned to bb937076de)