iced-rs/iced · error

Write last palette

Error message

Write last palette

What it means

After deciding the palette actually changed, `debug::theme_changed` records it with `METADATA.write().expect("Write last palette")`. The expect fires only when the RwLock is poisoned — an earlier panic held a guard — since the write itself cannot fail otherwise.

Source

Thrown at debug/src/lib.rs:175

    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()));
    }

    pub fn boot() -> Span {
        span(span::Stage::Boot)
    }

View on GitHub (pinned to 2cffa99b39)

Solutions

  1. Fix the root-cause panic that poisoned METADATA first
  2. Recover instead of panicking: `write().unwrap_or_else(PoisonError::into_inner)`
  3. Initialize debug state once at startup so later writes are single-threaded until the runtime spreads
  4. Disable the debug feature where it is not needed

Example fix

// before
METADATA.write().expect("Write last palette").theme = Some(palette);
// after
METADATA
    .write()
    .unwrap_or_else(std::sync::PoisonError::into_inner)
    .theme = Some(palette);
Defensive patterns

Strategy: fallback

Try / catch

let _ = std::panic::catch_unwind(|| debug::theme_changed(|| current_palette()));

Prevention

When it happens

Trigger: A theme change in a debug-instrumented app after the METADATA lock was poisoned by an earlier panic under one of its guards (init, BEACON LazyLock, or a prior theme_changed call).

Common situations: Debug builds with live theme switching after a swallowed panic; multiple threads logging theme events while a crash reporter masks the original failure.

Related errors


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