{"record":{"id":"d7f5c82e46da3d20","repo":"bevyengine/bevy","slug":"fatal-error-when-processing-text-e-d7f5c8","errorCode":null,"errorMessage":"Fatal error when processing text: {e}.","messagePattern":"Fatal error when processing text: (.+?)\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"crates/bevy_ui/src/widget/text.rs","lineNumber":353,"sourceCode":"                text_flags.needs_measure_fn = false;\n                text_flags.needs_recompute = true;\n            }\n            Err(\n                TextError::NoSuchFont\n                | TextError::NoSuchFontFamily(_)\n                | TextError::DegenerateScaleFactor,\n            ) => {\n                // Try again next frame\n                text_flags.needs_measure_fn = true;\n            }\n            Err(\n                e @ (TextError::FailedToAddGlyph(_)\n                | TextError::FailedToGetGlyphImage(_)\n                | TextError::MissingAtlasLayout\n                | TextError::MissingAtlasTexture\n                | TextError::InconsistentAtlasState),\n            ) => {\n                panic!(\"Fatal error when processing text: {e}.\");\n            }\n        };\n    }\n}\n\n/// Updates the layout and size information for a UI text node on changes to the size value of its [`Node`] component,\n/// or when the `needs_recompute` field of [`TextNodeFlags`] is set to true.\n/// This information is computed by the [`TextPipeline`] and then stored in [`TextLayoutInfo`].\n///\n/// ## World Resources\n///\n/// [`ResMut<Assets<Image>>`](Assets<Image>) -- This system only adds new [`Image`] assets.\n/// It does not modify or observe existing ones. The exception is when adding new glyphs to a [`bevy_text::FontAtlas`].\npub fn text_system(\n    mut textures: ResMut<Assets<Image>>,\n    mut font_atlas_set: ResMut<FontAtlasSet>,\n    mut text_pipeline: ResMut<TextPipeline>,\n    mut text_query: Query<(","sourceCodeStart":335,"sourceCodeEnd":371,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ui/src/widget/text.rs#L335-L371","documentation":"In measure_text_system (crates/bevy_ui/src/widget/text.rs), text processing errors are triaged: font-load failures and degenerate scale factors merely retry next frame, but FailedToAddGlyph, MissingAtlasLayout, MissingAtlasTexture, and InconsistentAtlasState are considered unrecoverable and trigger panic!(\"Fatal error when processing text: {e}.\"). These mean the glyph atlas is in a state where the text can never be measured, so Bevy aborts rather than loop forever.","triggerScenarios":"A broken, truncated, or unsupported font asset reaching the glyph rasterizer; glyph atlas textures/layouts being evicted or mutated unexpectedly; adding a glyph with malformed outline data; renderer state inconsistencies after GPU device loss.","commonSituations":"Loading a .ttf/.otf that is actually a renamed non-font file; using a hand-built or corrupted default font; swapping font assets at runtime while text entities reference the old handle; driver/device resets invalidating atlas textures; bugs in specific cosmic-text/bevy_text versions with certain scripts or emoji.","solutions":["Verify the font asset actually loads: check LoadState and log failures before spawning Text entities with it.","Fall back to a known-good font (e.g. the default FiraSans handle from the Font asset default) when a custom font fails to load.","Re-export or replace suspect font files (validate they open in a font editor) and confirm the byte content, not just the extension.","Isolate the offending Text entity by bisection (spawn subsets) to find which string/font triggers the glyph failure.","Update Bevy — glyph atlas handling fixes land regularly; pin to a version where your fonts render."],"exampleFix":"// before\ncommands.spawn((\n    Text::new(\"Title\"),\n    TextFont { font: assets.load(\"fonts/broken.ttf\"), ..default() },\n));\n\n// after: use a font that is known to load, or the default font\ncommands.spawn((\n    Text::new(\"Title\"),\n    TextFont { font: assets.load(\"fonts/FiraSans.ttf\"), ..default() },\n));","handlingStrategy":"fallback","validationCode":"use bevy_asset::{AssetServer, LoadState};\n\n// only spawn text once the font is confirmed loadable\nfn spawn_text_if_font_ok(assets: &AssetServer, font: &Handle<Font>) -> Handle<Font> {\n    match assets.get_load_state(font) {\n        Some(LoadState::Loaded) => font.clone(),\n        Some(LoadState::Failed(_)) => Handle::default(), // fall back to default font\n        _ => font.clone(), // still loading: acceptable, load errors retry next frame\n    }\n}","typeGuard":null,"tryCatchPattern":"// Not catchable in practice: this is a panic inside a system and aborts the app.\n// Replace the strategy with prevention: validate fonts up front and fall back to\n// a known-good default font when a custom font fails to load.","preventionTips":["Validate font files once at startup (open, check non-zero size, confirm LoadState::Loaded).","Never rename non-font files to .ttf; verify exports open in a font editor.","Pin a Bevy version where your fonts are known to render; retest text after upgrades.","Reproduce suspicious fonts with a minimal Text::new(\"abc\") entity before shipping."],"tags":["rust","bevy","bevy-ui","text","font","glyph","panic"],"backgroundTag":"font-glyph-atlas-failure","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-09T01:17:15.007Z"}