{"record":{"id":"ed05a50302451ac3","repo":"emilk/egui","slug":"plugin-of-type-not-found","errorCode":null,"errorMessage":"Plugin of type {:?} not found","messagePattern":"Plugin of type (.+?) not found","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/egui/src/context.rs","lineNumber":2153,"sourceCode":"    ///\n    /// Returns `None` if the plugin was not registered.\n    pub fn with_plugin<T: plugin::Plugin + 'static, R>(\n        &self,\n        f: impl FnOnce(&mut T) -> R,\n    ) -> Option<R> {\n        let plugin = self.read(|ctx| ctx.plugins.get(core::any::TypeId::of::<T>()));\n        plugin.map(|plugin| f(plugin.lock().typed_plugin_mut()))\n    }\n\n    /// Get a handle to the plugin of type `T`.\n    ///\n    /// ## Panics\n    /// If the plugin of type `T` was not registered, this will panic.\n    pub fn plugin<T: plugin::Plugin>(&self) -> TypedPluginHandle<T> {\n        if let Some(plugin) = self.plugin_opt() {\n            plugin\n        } else {\n            panic!(\"Plugin of type {:?} not found\", core::any::type_name::<T>());\n        }\n    }\n\n    /// Get a handle to the plugin of type `T`, if it was registered.\n    pub fn plugin_opt<T: plugin::Plugin>(&self) -> Option<TypedPluginHandle<T>> {\n        let plugin = self.read(|ctx| ctx.plugins.get(core::any::TypeId::of::<T>()));\n        plugin.map(TypedPluginHandle::new)\n    }\n\n    /// Get a handle to the plugin of type `T`, or insert its default.\n    pub fn plugin_or_default<T: plugin::Plugin + Default>(&self) -> TypedPluginHandle<T> {\n        if let Some(plugin) = self.plugin_opt() {\n            plugin\n        } else {\n            let default_plugin = T::default();\n            self.add_plugin(default_plugin);\n            self.plugin()\n        }","sourceCodeStart":2135,"sourceCodeEnd":2171,"githubUrl":"https://github.com/emilk/egui/blob/441971a776322a482e371775219380eca812cfa9/crates/egui/src/context.rs#L2135-L2171","documentation":"`Context::plugin::<T>()` looks up a registered plugin by type and returns a typed handle. If no plugin of type `T` was registered via `context.add_plugin(...)`, the lookup returns None and the method panics with the type name. It exists as a strict accessor; `plugin_opt::<T>()` is the non-panicking variant.","triggerScenarios":"Calling `ctx.plugin::<MyPlugin>()` where `ctx.add_plugin(MyPlugin::default())` was never called (or was called on a different Context instance), so `ctx.plugins` has no entry for `TypeId::of::<T>()`.","commonSituations":"Refactoring that removed the `add_plugin` call while retaining `plugin::<T>()` reads; ordering issues where plugin access happens before registration; sharing state via plugin across two different Context instances.","solutions":["Register the plugin first: call `ctx.add_plugin(MyPlugin::default())` before any `ctx.plugin::<MyPlugin>()` access.","Use `ctx.plugin_opt::<MyPlugin>()` and handle the None case when the plugin may legitimately be absent.","Confirm registration happens on the same `Context` object you're querying (not a re-created or clone-independent one).","Check initialization order: ensure add_plugin runs before the first frame/callback that reads the plugin."],"exampleFix":"// before\nlet plugin = ctx.plugin::<MyPlugin>(); // panics if not registered\n// after\nctx.add_plugin(MyPlugin::default());\nlet plugin = ctx.plugin::<MyPlugin>();\n// or non-panicking:\nif let Some(p) = ctx.plugin_opt::<MyPlugin>() { /* use p */ }","handlingStrategy":"type-guard","validationCode":"// check registration before strict access\nif ctx.plugin_opt::<MyPlugin>().is_none() {\n    ctx.add_plugin(MyPlugin::default());\n}","typeGuard":"fn has_plugin<T: egui::plugin::Plugin>(ctx: &egui::Context) -> bool {\n    ctx.plugin_opt::<T>().is_some()\n}","tryCatchPattern":"// Rust panics can't be caught portably (catch_unwind only); prefer:\nmatch ctx.plugin_opt::<MyPlugin>() {\n    Some(p) => use(p),\n    None => log::warn!(\"MyPlugin not registered\"),\n}","preventionTips":["Always pair every plugin::<T>() access with an add_plugin::<T>() at Context creation time.","Prefer plugin_opt::<T>() in library/optional paths; reserve plugin::<T>() for invariants.","Register plugins immediately after Context creation, before any frames or callbacks.","Keep a comment or debug_assert at access sites documenting the registration requirement."],"tags":["plugins","missing-registration","panic","lookup-failed"],"backgroundTag":"resource-not-found","analyzedSha":"441971a776322a482e371775219380eca812cfa9","analyzedAt":"2026-09-12T04:29:21.500Z","contentChangedAt":"2026-09-12T04:29:21.500Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}