{"record":{"id":"b67931c68815c5e3","repo":"iced-rs/iced","slug":"write-text-atlas","errorCode":null,"errorMessage":"Write text atlas","messagePattern":"Write text atlas","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"wgpu/src/text.rs","lineNumber":295,"sourceCode":"impl Pipeline {\n    pub fn new(device: &wgpu::Device, queue: &wgpu::Queue, format: wgpu::TextureFormat) -> Self {\n        let cache = cryoglyph::Cache::new(device);\n        let atlas =\n            cryoglyph::TextAtlas::with_color_mode(device, queue, &cache, format, COLOR_MODE);\n\n        Pipeline {\n            format,\n            cache,\n            atlas: Arc::new(RwLock::new(atlas)),\n        }\n    }\n\n    pub fn create_viewport(&self, device: &wgpu::Device) -> Viewport {\n        Viewport(cryoglyph::Viewport::new(device, &self.cache))\n    }\n\n    pub fn trim(&self) {\n        self.atlas.write().expect(\"Write text atlas\").trim();\n    }\n}\n\n#[derive(Default)]\npub struct State {\n    renderers: Vec<cryoglyph::TextRenderer>,\n    prepare_layer: usize,\n    cache: BufferCache,\n    storage: Storage,\n}\n\nimpl State {\n    pub fn new() -> Self {\n        Self::default()\n    }\n\n    pub fn prepare(\n        &mut self,","sourceCodeStart":277,"sourceCodeEnd":313,"githubUrl":"https://github.com/iced-rs/iced/blob/3de451447bd28217bb535632867550908e29d5d0/wgpu/src/text.rs#L277-L313","documentation":"The text pipeline keeps its cryoglyph TextAtlas behind an Arc<RwLock> shared by all renderers; Pipeline::trim acquires the write lock to evict unused glyphs. The expect fires when that lock is poisoned, i.e. a panic previously unwound while holding the atlas write lock inside State::prepare (glyph rasterization, layout, or the also-lock-protected font system).","triggerScenarios":"A panic during text preparation in an earlier frame (bad font data, a layout routine unwrapping on malformed content) poisoning the atlas lock; trim() then panics when the window is resized or widgets are dropped and cache trimming runs.","commonSituations":"Applications loading broken or missing fonts; long-lived apps that call renderer.trim() on memory pressure; a swallowed panic in an embedded runtime leaving the lock poisoned.","solutions":["Locate the original panic above this one in the crash trace and fix it (font loading or text layout)","Ship valid default fonts and validate user-supplied font files before use","Recover via unwrap_or_else(|poisoned| poisoned.into_inner()) in a patched iced if the process must survive"],"exampleFix":"// before (iced internals)\nself.atlas.write().expect(\"Write text atlas\").trim();\n\n// after\nself.atlas.write().unwrap_or_else(|poisoned| poisoned.into_inner()).trim();","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Recovery pattern for a poisoned atlas lock (patched iced or your own locks):\nlet mut atlas = match pipeline.atlas.write() {\n    Ok(guard) => guard,\n    Err(poisoned) => {\n        log::warn!(\"text atlas poisoned; recovering\");\n        poisoned.into_inner()\n    }\n};\natlas.trim();","preventionTips":["Load and validate all fonts at startup so prepare-time font code cannot panic later","Watch for the first text-related panic in logs; trim() failures are always downstream of it"],"tags":["wgpu","text-rendering","rwlock","poisoned-lock","font-atlas","rust"],"backgroundTag":"rwlock-poisoned","analyzedSha":"3de451447bd28217bb535632867550908e29d5d0","analyzedAt":"2026-08-17T10:40:26.997Z","contentChangedAt":"2026-08-17T10:40:26.997Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}