{"record":{"id":"58870f61c35c64ac","repo":"a-b-street/abstreet","slug":"can-t-find-widget","errorCode":null,"errorMessage":"Can't find widget {}","messagePattern":"Can't find widget (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"widgetry/src/widgets/panel.rs","lineNumber":491,"sourceCode":"    }\n\n    pub fn maybe_find_widget(&self, name: &str) -> Option<&Widget> {\n        self.top_level.find(name)\n    }\n\n    pub fn maybe_find<T: WidgetImpl>(&self, name: &str) -> Option<&T> {\n        self.maybe_find_widget(name).map(|w| {\n            if let Some(x) = w.widget.downcast_ref::<T>() {\n                x\n            } else {\n                panic!(\"Found widget {}, but wrong type\", name);\n            }\n        })\n    }\n\n    pub fn find<T: WidgetImpl>(&self, name: &str) -> &T {\n        self.maybe_find(name)\n            .unwrap_or_else(|| panic!(\"Can't find widget {}\", name))\n    }\n\n    pub fn find_mut<T: WidgetImpl>(&mut self, name: &str) -> &mut T {\n        if let Some(w) = self.top_level.find_mut(name) {\n            if let Some(x) = w.widget.downcast_mut::<T>() {\n                x\n            } else {\n                panic!(\"Found widget {}, but wrong type\", name);\n            }\n        } else {\n            panic!(\"Can't find widget {}\", name);\n        }\n    }\n\n    /// Swap the inner content of a `container` widget with `new_inner_content`.\n    pub(crate) fn swap_inner_content(\n        &mut self,\n        ctx: &EventCtx,","sourceCodeStart":473,"sourceCodeEnd":509,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/widgets/panel.rs#L473-L509","documentation":"`Panel::find::<T>` is the infallible variant of maybe_find: it panics when no widget with the given name exists in the panel. Callers (e.g. slider helpers) rely on the widget being present by construction.","triggerScenarios":"Calling `panel.find::<T>(name)` when the widget was never added, was removed by take/replace/swap_inner_content, or the name is misspelled.","commonSituations":"Panel content swapped dynamically so an expected widget no longer exists; typo in name; widget created inside a conditional branch that didn't run.","solutions":["Guard with `panel.has_widget(name)` before find","Use maybe_find::<T>() and handle the None case instead of find","Ensure the widget is always constructed and added (move creation out of conditionals)","Fix the name typo / keep names in constants"],"exampleFix":"// before\nlet s = panel.find::<Slider>(\"zoom\");\n// after\nif let Some(s) = panel.maybe_find::<Slider>(\"zoom\") { /* ... */ } else { /* rebuild content */ }","handlingStrategy":"type-guard","validationCode":"if panel.has_widget(\"zoom\") {\n    let s = panel.find::<Slider>(\"zoom\");\n}","typeGuard":"fn find_slider(panel: &Panel, name: &str) -> Option<&Slider> {\n    panel.maybe_find::<Slider>(name)\n}","tryCatchPattern":null,"preventionTips":["Prefer maybe_find over find when existence isn't guaranteed","Guard with has_widget before find","Keep panel-content construction unconditional for expected widgets"],"tags":["rust","panel","not-found","find"],"backgroundTag":"entity-not-found","analyzedSha":"0964f29315820c91b171b585eb51e300164e9197","analyzedAt":"2026-09-13T18:02:03.421Z","contentChangedAt":"2026-09-13T18:02:03.421Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}