iced-rs/iced · error
Read last palette
Error message
Read last palette
What it means
`debug::theme_changed` compares a freshly applied palette seed against the last one reported to the beacon; the `.read().expect("Read last palette")` fails when the global METADATA RwLock is poisoned by a prior panic under one of its guards. The closure `f` runs before locking, so the poison must originate elsewhere.
Source
Thrown at debug/src/lib.rs:172
};
}
pub fn quit() -> bool {
if BEACON.is_connected() {
BEACON.quit();
true
} else {
false
}
}
pub fn theme_changed(f: impl FnOnce() -> Option<palette::Seed>) {
let Some(palette) = f() else {
return;
};
if METADATA.read().expect("Read last palette").theme.as_ref() != Some(&palette) {
log(client::Event::ThemeChanged(palette));
METADATA.write().expect("Write last palette").theme = Some(palette);
}
}
pub fn tasks_spawned(amount: usize) {
log(client::Event::CommandsSpawned(amount));
}
pub fn subscriptions_tracked(amount: usize) {
log(client::Event::SubscriptionsTracked(amount));
}
pub fn layers_rendered(amount: impl FnOnce() -> usize) {
log(client::Event::LayersRendered(amount()));
}
View on GitHub (pinned to 2cffa99b39)
Solutions
- Locate the first panic that poisoned METADATA — this read is a cascade
- Recover from poison in the library: `read().unwrap_or_else(PoisonError::into_inner)`
- Keep panics out of code paths that hold METADATA guards (they are all inside debug/src/lib.rs)
- Ship without the debug feature in production
Example fix
// before
if METADATA.read().expect("Read last palette").theme.as_ref() != Some(&palette) {
// after
if METADATA
.read()
.unwrap_or_else(std::sync::PoisonError::into_inner)
.theme
.as_ref() != Some(&palette)
{ Defensive patterns
Strategy: fallback
Try / catch
let _ = std::panic::catch_unwind(|| debug::theme_changed(|| current_palette()));
Prevention
- Fix the root-cause panic that poisoned METADATA — theme logging is a victim, not the cause
- Avoid continuing to run after a swallowed panic in debug-instrumented builds
- Keep theme_changed callbacks cheap and panic-free; they run on every theme swap
- Run stress scenarios with the debug feature off to isolate rendering bugs from telemetry bugs
When it happens
Trigger: Every theme/palette change in an app built with iced's debug feature, once the METADATA lock has been poisoned by an earlier panic (e.g. inside BEACON initialization or a previous theme_changed write).
Common situations: Live theme switching during a debug session after any swallowed panic; multithreaded apps where a panic on a worker thread poisoned METADATA before the UI thread changed themes.
Related errors
- Write last palette
- Write application metadata
- Read application metadata
- Lock hot functions
- Write to font system
AI-assisted analysis of iced-rs/iced@2cffa99b39 (2026-08-16).
Data as JSON: /api/errors/9bc29db229186edc.
Report an issue: GitHub.