a-b-street/abstreet · error
Can't take( ), it's a top-level widget
Error message
Can't take({}), it's a top-level widget What it means
`take` removes a nested named widget from a Panel's tree and returns it, but the top-level widget itself cannot be removed without destroying the Panel. Panics if the requested name matches the top-level widget.
Solutions
- Use a child/container widget name, not the root's name
- If you need to replace the whole content, use replace or set_content instead of take
- Check with has_widget and ensure the target is nested
Defensive patterns
Strategy: validation
Validate before calling
if panel.has_widget(name) && name != ROOT_NAME { /* take is safe to attempt */ } Prevention
- Never target the root widget with take
- Use replace/set_content for top-level changes
- Track root's name in a constant to compare against
When it happens
Trigger: Calling `Panel::take(name)` where `name` is the id of the Panel's top-level (root) widget.
Common situations: Assuming take works on any named widget including the root; passing the panel's own name because it was set via `.named(...)` on the root.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Can't delete ; it's not in the World
- Can't delete mid-drag
- Dropdown has default_value , but none of the choices match…
- Failed to load svg from bytes. cache_key
- Two buttons in one Panel both use action
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/ea26a3f4b71ad976.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/widgets/mod.rs:811
fn find_mut(&mut self, name: &str) -> Option<&mut Widget> {
if self.id == Some(name.to_string()) {
return Some(self);
}
if let Some(container) = self.widget.downcast_mut::<Container>() {
for widget in &mut container.members {
if let Some(w) = widget.find_mut(name) {
return Some(w);
}
}
}
None
}
fn take(&mut self, name: &str) -> Option<Widget> {
if self.id == Some(name.to_string()) {
panic!("Can't take({}), it's a top-level widget", name);
}
if let Some(container) = self.widget.downcast_mut::<Container>() {
let mut members = Vec::new();
let mut found = None;
for mut widget in container.members.drain(..) {
if widget.id == Some(name.to_string()) {
found = Some(widget);
} else if let Some(w) = widget.take(name) {
found = Some(w);
members.push(widget);
} else {
members.push(widget);
}
}
found
} else {
NoneView on GitHub (pinned to 0964f29315)