{"record":{"id":"2026e2dd4fbb2365","repo":"emilk/egui","slug":"no-fonts-available-until-first-call-to-context-ru","errorCode":null,"errorMessage":"No fonts available until first call to Context::run()","messagePattern":"No fonts available until first call to Context::run\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/egui/src/context.rs","lineNumber":1316,"sourceCode":"    ///\n    /// This is swapped at the end of each pass.\n    #[inline]\n    pub(crate) fn prev_pass_state<R>(&self, reader: impl FnOnce(&PassState) -> R) -> R {\n        self.write(move |ctx| reader(&ctx.viewport().prev_pass))\n    }\n\n    /// Read-only access to [`Fonts`].\n    ///\n    /// Not valid until first call to [`Context::run_ui()`].\n    /// That's because since we don't know the proper `pixels_per_point` until then.\n    #[inline]\n    pub fn fonts<R>(&self, reader: impl FnOnce(&FontsView<'_>) -> R) -> R {\n        self.write(move |ctx| {\n            let pixels_per_point = ctx.pixels_per_point();\n            reader(\n                &ctx.fonts\n                    .as_mut()\n                    .expect(\"No fonts available until first call to Context::run()\")\n                    .with_pixels_per_point(pixels_per_point),\n            )\n        })\n    }\n\n    /// Read-write access to [`Fonts`].\n    ///\n    /// Not valid until first call to [`Context::run_ui()`].\n    /// That's because since we don't know the proper `pixels_per_point` until then.\n    #[inline]\n    pub fn fonts_mut<R>(&self, reader: impl FnOnce(&mut FontsView<'_>) -> R) -> R {\n        self.write(move |ctx| {\n            let pixels_per_point = ctx.pixels_per_point();\n            reader(\n                &mut ctx\n                    .fonts\n                    .as_mut()\n                    .expect(\"No fonts available until first call to Context::run()\")","sourceCodeStart":1298,"sourceCodeEnd":1334,"githubUrl":"https://github.com/emilk/egui/blob/8fb03c9ae9a6bf1ffa602dfba51ed575f2655975/crates/egui/src/context.rs#L1298-L1334","documentation":"Context::fonts() gives read-write access to egui's Fonts via a closure, but fonts are only initialized during the first pass started by Context::run(). Before that, ctx.fonts is None and the expect panics. This is an initialization-order guard: font-dependent APIs are meaningless before the first frame.","triggerScenarios":"Calling ctx.fonts(...) (write access variant, context.rs:1163) before the first Context::run()/BeginPass call, e.g. during backend setup, in a constructor, or in a test that builds a Context directly.","commonSituations":"Measuring text or querying font layout in app initialization code before the eframe update loop starts; unit tests constructing Context::default() and immediately reading fonts; plugins reading fonts in an init hook.","solutions":["Move the ctx.fonts() call into your frame callback (inside Context::run / eframe's update fn)","Defer any text-metric-dependent setup until the first frame executes","If you need fonts before the first frame, call Context::run (or begin_pass/end_pass) once beforehand","In tests, use an initialized harness (e.g. run one pass) before asserting on fonts"],"exampleFix":"// before\nlet ctx = egui::Context::default();\nlet h = ctx.fonts(|f| f.layout_no_wrap(\"hi\".into(), id, color)); // panics\n// after\nlet ctx = egui::Context::default();\nctx.run(Instant::now(), |ctx| {\n    let h = ctx.fonts(|f| f.layout_no_wrap(\"hi\".into(), id, color));\n});","handlingStrategy":"validation","validationCode":"// Rust: guard before querying fonts\nif !ctx.will_discard() && has_run_once(ctx) {\n    ctx.fonts(|f| /* ... */);\n}","typeGuard":"fn fonts_available(ctx: &egui::Context) -> bool {\n    ctx.memory(|m| !m.areas.is_empty()) // implies at least one pass ran\n}","tryCatchPattern":null,"preventionTips":["Only access fonts inside frame callbacks","Never query fonts during app/Context construction","Run one pass in tests before font assertions","Cache font metrics after first frame instead of startup"],"tags":["egui","fonts","initialization","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"}