a-b-street/abstreet · error
Panel doesn't have
Error message
Panel doesn't have {} What it means
Panel::replace swaps the widget with the given ID for a new one. This fires when top_level.find_mut(id) returns None — the panel contains no widget with that ID, so the caller is trying to replace a widget that was never added or was already removed/taken. It is a UI programming-error guard.
Solutions
- Check `panel.has_widget(id)` before replace; add the widget instead if missing
- Ensure the original widget was named with `.named(id)` so find_mut can locate it
- Don't take() a widget you later intend to replace — replace returns the old one if needed via other APIs
- Verify content-rebuild logic always inserts the widget being replaced
Example fix
// before
panel.replace(ctx, "row3", new_row); // panics if absent
// after
if panel.has_widget("row3") {
panel.replace(ctx, "row3", new_row);
} else {
panel.add_widget(new_row.named("row3"));
} Defensive patterns
Strategy: validation
Validate before calling
if panel.has_widget("row3") {
panel.replace(ctx, "row3", new_row.named("row3"));
} Prevention
- Check has_widget before replace; add instead when missing
- Ensure widgets are .named(id) at construction
- Avoid take() on widgets you will later replace
When it happens
Trigger: Calling `panel.replace(ctx, "row3", new_widget)` where "row3" was never added, already removed via take, or its name changed after swap_inner_content.
Common situations: Rebuilding panel contents dynamically and replacing a row that a conditional branch skipped; typos in id; replacing after take consumed the original.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- Can't scroll_to_member of unknown
- Can't find widget
- Two buttons in one Panel both use action
- Can't take( ), it's a top-level widget
- Found widget , but wrong type
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/48cc795f73ff74e0.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/widgets/panel.rs:556
pub fn replace(&mut self, ctx: &mut EventCtx, id: &str, mut new: Widget) {
if let Some(ref new_id) = new.id {
assert_eq!(id, new_id);
}
new = new.named(id);
let old = self
.top_level
.find_mut(id)
.unwrap_or_else(|| panic!("Panel doesn't have {}", id));
new.layout.style = old.layout.style;
*old = new;
self.recompute_layout(ctx, true);
}View on GitHub (pinned to 0964f29315)