{"record":{"id":"cb915b73dbb9bbff","repo":"emilk/egui","slug":"no-fonts-loaded","errorCode":null,"errorMessage":"No fonts loaded","messagePattern":"No fonts loaded","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/egui/src/context.rs","lineNumber":3222,"sourceCode":"        shapes: Vec<ClippedShape>,\n        pixels_per_point: f32,\n    ) -> Vec<ClippedPrimitive> {\n        profiling::function_scope!();\n\n        // A tempting optimization is to reuse the tessellation from last frame if the\n        // shapes are the same, but just comparing the shapes takes about 50% of the time\n        // it takes to tessellate them, so it is not a worth optimization.\n\n        self.write(|ctx| {\n            let tessellation_options = ctx.memory.options.tessellation_options;\n            let texture_atlas = if let Some(fonts) = ctx.fonts.as_ref() {\n                fonts.texture_atlas()\n            } else {\n                log::warn!(\"No font size matching {pixels_per_point} pixels per point found.\");\n                ctx.fonts\n                    .iter()\n                    .next()\n                    .expect(\"No fonts loaded\")\n                    .texture_atlas()\n            };\n\n            let paint_stats = PaintStats::from_shapes(&shapes);\n            let clipped_primitives = {\n                profiling::scope!(\"tessellator::tessellate_shapes\");\n                tessellator::Tessellator::new(\n                    pixels_per_point,\n                    tessellation_options,\n                    texture_atlas.size(),\n                    texture_atlas.prepared_discs(),\n                )\n                .tessellate_shapes(shapes)\n            };\n            ctx.paint_stats = paint_stats.with_clipped_primitives(&clipped_primitives);\n            clipped_primitives\n        })\n    }","sourceCodeStart":3204,"sourceCodeEnd":3240,"githubUrl":"https://github.com/emilk/egui/blob/8fb03c9ae9a6bf1ffa602dfba51ed575f2655975/crates/egui/src/context.rs#L3204-L3240","documentation":"In Context::tessellate (context.rs:3067), when the requested pixels_per_point has no exact font-size match, egui falls back to the first available font entry and expects at least one to exist. The panic 'No fonts loaded' means ctx.fonts is None or empty — fonts were never initialized because Context::run() has not run yet, so tessellation cannot proceed.","triggerScenarios":"Calling ctx.tessellate/shapes-to-primitives APIs before the first Context::run()/pass; rendering shapes collected outside the frame loop on a fresh Context.","commonSituations":"Custom integration code that tessellates egui shapes in its own render loop without running the egui context; rendering buffered shapes from a previous pass on a newly constructed Context; backend drawing paths invoked before egui's first update.","solutions":["Ensure Context::run executes (at least one pass) before calling tessellate on shapes","Register fonts explicitly via Context::set_fonts before tessellating outside the normal loop","Tessellate the shapes returned within the same pass that produced them","Check that your integration isn't re-creating the Context each frame, losing font state"],"exampleFix":"// before\nlet shapes = memory.shapes; // on a fresh Context\nlet prims = ctx.tessellate(shapes); // panics: no fonts loaded\n// after\nctx.run(input, |ctx| {\n    let prims = ctx.tessellate(ctx draining shapes);\n});","handlingStrategy":"validation","validationCode":"// Rust: ensure fonts exist before tessellating\nlet has_fonts = ctx.run(input, |ctx| ctx.tessellate(shapes)); // tessellate only post-run","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Call tessellate only after at least one Context::run pass","Call Context::set_fonts before off-loop tessellation","Tessellate shapes within the same pass they were produced","Avoid recreating the Context between shape collection and tessellation"],"tags":["egui","fonts","tessellation","panic"],"backgroundTag":"invalid-state-transition","analyzedSha":"8fb03c9ae9a6bf1ffa602dfba51ed575f2655975","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}