{"record":{"id":"8a4f436a2795de44","repo":"iced-rs/iced","slug":"write-application-metadata","errorCode":null,"errorMessage":"Write application metadata","messagePattern":"Write application metadata","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"debug/src/lib.rs","lineNumber":150,"sourceCode":"    use crate::core::time::Instant;\n    use crate::core::window;\n    use crate::futures::Subscription;\n    use crate::futures::futures::Stream;\n    use crate::{Command, Metadata, Primitive};\n\n    use iced_beacon as beacon;\n\n    use beacon::client::{self, Client};\n    use beacon::span;\n    use beacon::span::present;\n\n    use std::sync::atomic::{self, AtomicBool, AtomicUsize};\n    use std::sync::{LazyLock, RwLock};\n\n    pub fn init(metadata: Metadata) {\n        let name = metadata.name.split(\"::\").next().unwrap_or(metadata.name);\n\n        *METADATA.write().expect(\"Write application metadata\") = client::Metadata {\n            name,\n            theme: metadata.theme,\n            can_time_travel: metadata.can_time_travel,\n        };\n    }\n\n    pub fn quit() -> bool {\n        if BEACON.is_connected() {\n            BEACON.quit();\n\n            true\n        } else {\n            false\n        }\n    }\n\n    pub fn theme_changed(f: impl FnOnce() -> Option<palette::Seed>) {\n        let Some(palette) = f() else {","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/iced-rs/iced/blob/2cffa99b395d84fe469b44dccb56bbacd2f1a157/debug/src/lib.rs#L132-L168","documentation":"With iced's debug instrumentation enabled, `debug::init` stores the application `Metadata` (name, theme, time-travel capability) in a global `RwLock`. The `.expect(\"Write application metadata\")` panics when that lock is poisoned by an earlier panic that occurred while a METADATA guard was held; re-entrant init while the BEACON LazyLock holds the read lock would deadlock instead.","triggerScenarios":"Calling `debug::init(metadata)` once the METADATA RwLock is already poisoned — e.g. a prior panic inside theme_changed or BEACON initialization on another thread left it poisoned. Also reachable if init is called lazily (on first log event) rather than at startup, racing other debug calls.","commonSituations":"Debug feature enabled under stress tests where an unrelated earlier panic poisoned the static; a crash-reporting wrapper that swallows the first panic so only this cascade is visible; calling init from multiple threads.","solutions":["Find the ORIGINAL panic that poisoned METADATA — this expect is secondary","Call debug::init exactly once, at program start, before spawning tasks/threads that log events","As a maintainer: `write().unwrap_or_else(PoisonError::into_inner)` keeps debug telemetry alive after poisoning","Disable the debug feature in release builds to remove the surface entirely"],"exampleFix":"// before\n*METADATA.write().expect(\"Write application metadata\") = client::Metadata { .. };\n// after\n*METADATA.write().unwrap_or_else(std::sync::PoisonError::into_inner) = client::Metadata { .. };","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// don't let debug telemetry abort the app\nlet _ = std::panic::catch_unwind(|| debug::init(metadata));","preventionTips":["Call debug::init exactly once at program start, before spawning threads or tasks","Remember this panic is a cascade: hunt the earlier panic that poisoned METADATA first","Disable the debug feature in release/CI runs where telemetry is not the subject under test","If you maintain a fork, use unwrap_or_else(PoisonError::into_inner) on METADATA guards"],"tags":["rust","iced","debug","rwlock","lock-poisoning","panic","metadata"],"backgroundTag":"lock-poisoned","analyzedSha":"2cffa99b395d84fe469b44dccb56bbacd2f1a157","analyzedAt":"2026-08-16T19:41:49.083Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}