iced-rs/iced · error

Read from font system

Error message

Read from font system

What it means

`Compositor::list_fonts` snapshots family names from the global font system under a read lock; `.expect("Read from font system")` fires only when the RwLock is poisoned by a prior panic under one of its guards. This path serves the debug/devtools UI that enumerates installed families.

Source

Thrown at graphics/src/compositor.rs:70

    /// Loads a font from its bytes.
    fn load_font(&mut self, font: Cow<'static, [u8]>) -> Result<(), font::Error> {
        crate::text::font_system()
            .write()
            .expect("Write to font system")
            .load_font(font);

        // TODO: Error handling
        Ok(())
    }

    /// Lists all the available font families.
    fn list_fonts(&mut self) -> Result<Vec<font::Family>, font::Error> {
        use std::collections::BTreeSet;

        let font_system = crate::text::font_system()
            .read()
            .expect("Read from font system");

        let families = BTreeSet::from_iter(font_system.families());

        Ok(families.into_iter().map(font::Family::name).collect())
    }

    /// Presents the [`Renderer`] primitives to the next frame of the given [`Surface`].
    ///
    /// [`Renderer`]: Self::Renderer
    /// [`Surface`]: Self::Surface
    fn present(
        &mut self,
        renderer: &mut Self::Renderer,
        surface: &mut Self::Surface,
        viewport: &Viewport,
        background_color: Color,
        on_pre_present: impl FnOnce(),
    ) -> Result<(), SurfaceError>;

View on GitHub (pinned to 2cffa99b39)

Solutions

  1. Trace the first panic that poisoned the font-system lock — the read failure is downstream
  2. Recover from poison: `read().unwrap_or_else(PoisonError::into_inner)`
  3. Load fonts before starting threads that lay out text, so the lock is effectively uncontended
  4. Keep the debug/devtools UI off in sessions where you are diagnosing text panics

Example fix

// before
let font_system = crate::text::font_system().read().expect("Read from font system");
// after
let font_system = crate::text::font_system()
    .read()
    .unwrap_or_else(std::sync::PoisonError::into_inner);
Defensive patterns

Strategy: validation

Prevention

When it happens

Trigger: Opening the font list in iced's debug tooling (beacon/devtools) or calling list_fonts after the shared font-system lock was poisoned by an earlier text-pipeline panic; concurrently with load_font writes on a poisoned lock.

Common situations: Debug UI introspecting fonts during a session where a render thread already panicked inside layout/shaping; hot font loading combined with a swallowed first panic.

Related errors


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