louis-e/arnis · info

bundled font atlas is valid

Error message

bundled font atlas is valid

What it means

The bundled font atlas is decoded at startup via `FONT_ASSETS` -> `Font::parse(png, idx).expect("bundled font atlas is valid")`. The library authors consider the embedded PNG/index pairs compile-time constants that must always parse, so a failure panics instead of returning an error. Hitting it means the bundled binary assets are corrupt or `Font::parse` regressed on them.

Source

Thrown at src/decals/font.rs:67

    line_height: u8,
    glyphs: HashMap<char, Glyph>,
}

macro_rules! font_assets {
    ($($size:literal),*) => {
        [$((
            include_bytes!(concat!("../../assets/decorations/font/dejavu_bold_", $size, ".png")) as &[u8],
            include_bytes!(concat!("../../assets/decorations/font/dejavu_bold_", $size, ".bin")) as &[u8],
        )),*]
    };
}

static FONT_ASSETS: [(&[u8], &[u8]); 5] = font_assets!("12", "18", "28", "44", "64");

static FONTS: Lazy<Vec<Font>> = Lazy::new(|| {
    FONT_ASSETS
        .iter()
        .map(|(png, idx)| Font::parse(png, idx).expect("bundled font atlas is valid"))
        .collect()
});

impl Font {
    fn parse(png: &[u8], idx: &[u8]) -> Result<Font, String> {
        let atlas = image::load_from_memory(png)
            .map_err(|e| format!("font atlas: {e}"))?
            .to_luma8();
        if idx.len() < 8 || &idx[0..4] != b"AFN1" {
            return Err("font index: bad magic".to_string());
        }
        let line_height = idx[4];
        let count = u16::from_le_bytes([idx[6], idx[7]]) as usize;
        let mut glyphs = HashMap::with_capacity(count);
        let mut off = 8;
        for _ in 0..count {
            if off + 9 > idx.len() {
                return Err("font index: truncated".to_string());

View on GitHub (pinned to 34048924d9)

Solutions

  1. Restore the original bundled font PNG/index assets (git checkout the asset files)
  2. Rebuild from a clean checkout to rule out corrupted build artifacts
  3. If a dependency (image decoder) was upgraded, downgrade or fix `Font::parse` for the new decoder output
  4. Replace `expect` with proper error propagation during development of custom fonts

Example fix

// before
Font::parse(png, idx).expect("bundled font atlas is valid")
// after
Font::parse(png, idx).map_err(|e| format!("font atlas {name:?} invalid: {e}"))?
Defensive patterns

Strategy: fallback

Validate before calling

let parsed: Result<Vec<_>, String> = FONT_ASSETS.iter().map(|(p,i)| Font::parse(p,i)).collect();

Try / catch

// Wrap FONTS initialization so a parse failure logs and falls back to a default font instead of panicking at first use

Prevention

When it happens

Trigger: Practically only when the font asset bytes were replaced or corrupted (custom build, bad merge, build script mangling `include_bytes!` sources) or a `Font::parse` code change broke decoding of a previously valid atlas format.

Common situations: Patching the bundled asset files or the image/decoding dependency to an incompatible version; a build step that rewrites or compresses assets; partial checkout/corrupted repository.

Related errors


AI-assisted analysis of louis-e/arnis@34048924d9 (2026-09-03). Data as JSON: /api/errors/8cbde26d00d47c3b. Report an issue: GitHub.