iced-rs/iced · error
Write to text atlas
Error message
Write to text atlas
What it means
State::prepare acquires the write lock on the shared text atlas before laying out and rasterizing each text batch with cryoglyph (iced's glyphon fork). The expect on pipeline.atlas.write() panics when the lock is already poisoned by an earlier panic that unwound while holding it, including panics from the nested font_system().write() lock taken inside the same function.
Source
Thrown at wgpu/src/text.rs:323
}
impl State {
pub fn new() -> Self {
Self::default()
}
pub fn prepare(
&mut self,
pipeline: &Pipeline,
device: &wgpu::Device,
queue: &wgpu::Queue,
viewport: &Viewport,
encoder: &mut wgpu::CommandEncoder,
batch: &Batch,
layer_bounds: Rectangle,
layer_transformation: Transformation,
) {
let mut atlas = pipeline.atlas.write().expect("Write to text atlas");
for item in batch {
match item {
Item::Group {
transformation,
text,
} => {
if self.renderers.len() <= self.prepare_layer {
self.renderers.push(cryoglyph::TextRenderer::new(
&mut atlas,
device,
wgpu::MultisampleState::default(),
None,
));
}
let renderer = &mut self.renderers[self.prepare_layer];
let result = prepare(View on GitHub (pinned to 3de451447b)
Solutions
- Fix the first text-related panic in the log; this expect is downstream damage
- Pre-load and validate fonts at startup instead of lazily during prepare
- Reproduce with debug symbols to identify whether the poisoner is the atlas or font-system lock and report to iced
Example fix
// before (iced internals)
let mut atlas = pipeline.atlas.write().expect("Write to text atlas");
// after
let mut atlas = pipeline
.atlas
.write()
.unwrap_or_else(|poisoned| poisoned.into_inner()); Defensive patterns
Strategy: try-catch
Try / catch
// If you embed iced and cannot guarantee panic-free text pipelines,
// fence the frame so a panic never unwinds through the atlas lock twice:
match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
compositor.present(&mut renderer, &mut surface, &viewport, background, || {})
})) {
Ok(result) => result?,
Err(payload) => {
log::error!("frame panicked: {payload:?}; recreating window state");
// rebuild compositor/surface state instead of reusing poisoned locks
}
} Prevention
- Validate custom font bytes before handing them to the font system
- In multi-window apps, isolate windows so one poisoned pipeline does not take down every window sharing the Engine
When it happens
Trigger: A previous frame's text preparation panicked (font parsing failure, unwrap on malformed shaped text, a user callback in the text pipeline) while holding the atlas write guard; every subsequent frame then aborts at this line. In multi-window apps any window sharing the Pipeline can be the poisoner.
Common situations: Dynamic font loading of corrupt files; edge-case glyphs (rare scripts, color emoji) hitting rasterizer panics; one poisoned window cascading to all windows of the process.
Related errors
- Write text atlas
- Read text atlas
- primitive storage should be writable
- Write primitive storage
- Read primitive storage
AI-assisted analysis of iced-rs/iced@3de451447b (2026-08-17).
Data as JSON: /api/errors/b7742e41e0694e18.
Report an issue: GitHub.