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

  1. Locate the first panic that poisoned METADATA — this read is a cascade
  2. Recover from poison in the library: `read().unwrap_or_else(PoisonError::into_inner)`
  3. Keep panics out of code paths that hold METADATA guards (they are all inside debug/src/lib.rs)
  4. 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

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


AI-assisted analysis of iced-rs/iced@2cffa99b39 (2026-08-16). Data as JSON: /api/errors/9bc29db229186edc. Report an issue: GitHub.