emilk/egui · critical

No font data found for {name:?}. Configured fonts: {availabl

Error message

No font data found for {name:?}. Configured fonts: {available:?}

What it means

`fonts_for_family` looks up each font name registered for a family in `self.font_data` and panics if a name has no corresponding entry. This is an internal consistency check: every name in `FontDefinitions::families` must have an entry in `font_data`, otherwise the family configuration is broken.

Source

Thrown at crates/epaint/src/text/font_definitions.rs:249

/// The configured fonts are the head of every family's fallback chain:
/// for each family they are handed out in the order they are listed,
/// so the same text looks the same on every machine.
///
/// [`FontDefinitions`] never discovers anything on demand,
/// and is always the first [`FontProvider`] asked.
impl FontProvider for FontDefinitions {
    fn fonts_for_family(&self, family: &FontFamily) -> Vec<FontInsert> {
        let Some(font_names) = self.families.get(family) else {
            log::warn!("FontFamily::{family:?} is not bound to any fonts");
            return Vec::new();
        };

        font_names
            .iter()
            .map(|name| {
                let data = self.font_data.get(name).unwrap_or_else(|| {
                    let available: Vec<&String> = self.font_data.keys().collect();
                    panic!("No font data found for {name:?}. Configured fonts: {available:?}")
                });
                FontInsert {
                    name: name.clone(),
                    data: (**data).clone(),
                    families: Vec::new(),
                }
            })
            .collect()
    }
}

View on GitHub (pinned to 441971a776)

Solutions

  1. Make sure every name listed in `families` has an identical key in `font_data` — fix typos/case so they match exactly.
  2. If you removed font data, also remove the name from the family's font list.
  3. Use the panic message's `Configured fonts:` list to see the exact valid keys and pick/correct to one of them.
  4. Build the definitions with a helper that inserts data and registers the family name in one place to keep them in sync.

Example fix

// before
fonts.families.get_mut(&FontFamily::Monospace).unwrap().push("JetBrainsMono".into());
fonts.font_data.insert("JetBrains Mono".into(), Cow::Owned(data));
// after
let key = "JetBrainsMono";
fonts.font_data.insert(key.to_owned(), Cow::Owned(data));
fonts.families.get_mut(&FontFamily::Monospace).unwrap().push(key.to_owned());
Defensive patterns

Strategy: validation

Validate before calling

// Before using definitions, verify family names all resolve
for (family, names) in &defs.families {
    for name in names {
        assert!(defs.font_data.contains_key(name), "font {name:?} missing from font_data");
    }
}

Type guard

fn fonts_resolvable(defs: &FontDefinitions) -> bool {
    defs.families.values().flatten().all(|n| defs.font_data.contains_key(n))
}

Try / catch

// Panic-based; check membership before handing definitions to egui
assert!(defs.font_data.contains_key(font_name), "register {font_name} in font_data before listing it");

Prevention

When it happens

Trigger: Pushing a font name into `FontDefinitions::families` (or configuring fonts via kittest/egui config) without inserting matching data into `font_data` under the exact same string — including case, spaces, and file extension.

Common situations: Typos or case mismatches between the family list name and the `font_data` map key; removing a `font_data.insert(...)` while leaving the name in the families vec; copying config from an example with different font keys; serialization round-trips dropping `font_data`.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of emilk/egui@441971a776 (2026-09-12). Data as JSON: /api/errors/66160778c0a28b21. Report an issue: GitHub.