a-b-street/abstreet · error
Found widget , but wrong type
Error message
Found widget {}, but wrong type What it means
`Panel::maybe_find::<T>` looks up a widget by name and downcasts to T; if a widget with that name exists but is a different concrete type than requested, the API contract is broken and it panics instead of returning a confusing reference.
Solutions
- Annotate the generic type explicitly and match the widget's actual type: maybe_find::<Button>("save_btn")
- Rename the widget or update call sites after changing its type
- Use maybe_find_widget to inspect the Widget and confirm its type before downcasting
Example fix
// before
let btn = panel.maybe_find::<Slider>("save_btn"); // save_btn is a Button
// after
let btn = panel.maybe_find::<Button>("save_btn"); Defensive patterns
Strategy: type-guard
Validate before calling
if panel.has_widget("save_btn") {
let w = panel.maybe_find_widget("save_btn").unwrap();
let is_button = w.widget.downcast_ref::<Button>().is_some();
} Type guard
fn is_button(panel: &Panel, name: &str) -> bool {
panel.maybe_find_widget(name)
.map(|w| w.widget.downcast_ref::<Button>().is_some())
.unwrap_or(false)
} Prevention
- Annotate generics explicitly at find call sites
- Update call sites whenever a widget's type changes
- Encode widget type in names
When it happens
Trigger: `panel.maybe_find::<Button>("x")` (or `find`) where "x" names a Widget of another type, e.g. a Slider or Label — maybe_find_widget succeeds, downcast_ref::<T> fails.
Common situations: Changing a widget's type during refactoring (Label -> Button) without updating find calls; two similarly-named widgets; calling find with the wrong generic parameter inferred by the compiler.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- expected turn, but found
- Two buttons in one Panel both use action
- Can't take( ), it's a top-level widget
- Can't scroll_to_member of unknown
- Can't find widget
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/626fa9e1d96d0793.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/widgets/panel.rs:484
/// Grab a stashed value and clone it.
pub fn clone_stashed<T: 'static + Clone>(&self, name: &str) -> T {
self.find::<Stash<T>>(name).get_value().borrow().clone()
}
pub fn is_button_enabled(&self, name: &str) -> bool {
self.find::<Button>(name).is_enabled()
}
pub fn maybe_find_widget(&self, name: &str) -> Option<&Widget> {
self.top_level.find(name)
}
pub fn maybe_find<T: WidgetImpl>(&self, name: &str) -> Option<&T> {
self.maybe_find_widget(name).map(|w| {
if let Some(x) = w.widget.downcast_ref::<T>() {
x
} else {
panic!("Found widget {}, but wrong type", name);
}
})
}
pub fn find<T: WidgetImpl>(&self, name: &str) -> &T {
self.maybe_find(name)
.unwrap_or_else(|| panic!("Can't find widget {}", name))
}
pub fn find_mut<T: WidgetImpl>(&mut self, name: &str) -> &mut T {
if let Some(w) = self.top_level.find_mut(name) {
if let Some(x) = w.widget.downcast_mut::<T>() {
x
} else {
panic!("Found widget {}, but wrong type", name);
}
} else {
panic!("Can't find widget {}", name);View on GitHub (pinned to 0964f29315)