a-b-street/abstreet · error
Initial panel outcome is
Error message
Initial panel outcome is {}. Consider calling ignore_initial_events What it means
widgetry's Panel::build_custom runs the panel's event handler once inside a no-op event pass to initialize it. If the very first event already produces a non-Nothing Outcome (e.g. a button click or state change), the library panics, because a panel should not fire an action before the user interacts with it. The message suggests using ignore_initial_events to suppress that first outcome.
Solutions
- Pass ignore_initial_events: true to build_custom if the initial outcome is expected and harmless.
- Fix the widget so it produces Outcome::Nothing on its first (synthetic) event, e.g. skip processing until after initialization.
- Guard the widget's event handler against the initial no-op pass (check ctx.input state before emitting an outcome).
Example fix
// before
let panel = Panel::build(ctx, |panel, ctx| { ... });
// after
let panel = Panel::build_custom(ctx, |panel, ctx| { ... }, true /* ignore_initial_events */); Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure widgets emit Outcome::Nothing on the first event, or plan to use ignore_initial_events let uses_ignore = true; // decide before building
Try / catch
// Since this panics (not a Result), avoid it by construction:
let panel = Panel::build_custom(ctx, |panel, ctx| { ... }, /* ignore_initial_events */ true); Prevention
- Always pass ignore_initial_events=true for panels containing stateful widgets (checkboxes, sliders).
- Test new panels in a headless/no-op event pass before shipping.
- Make custom Widgets emit Outcome::Nothing during initialization.
When it happens
Trigger: Calling Panel::build_custom with ignore_initial_events=false when the panel's initial layout or event handler immediately returns a non-Nothing Outcome (e.g. a checkbox whose initial state triggers a change, a button focused and activated during construction, custom widgets that emit outcomes in their first event call).
Common situations: Panels with widgets whose initial render triggers a click/change handler; custom Widgets implemented in a way that reacts to the synthetic initial event; recent refactors that added a widget whose initial event mutates state.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Can't delete ; it's not in the World
- Can't delete mid-drag
- Failed to load svg from bytes. cache_key
- invalid tab id
- This build of A/B Street stores player data in…
AI-assisted analysis of a-b-street/abstreet@0964f29315 (2026-09-13).
Data as JSON: /api/errors/0f55bcb3395fbccd.
Report an issue: GitHub.
Appendix: source
Thrown at widgetry/src/widgets/panel.rs:668
// TODO: to support Panel's that can resize their `contents_dims`, we'll need to detangle
// this dependency. This might entail decomposing the flexbox calculation to layout first
// the inner content, and then potentially a second pass to layout any x/y scrollbars.
panel.recompute_layout(ctx, false);
panel.contents_dims =
ScreenDims::new(panel.top_level.rect.width(), panel.top_level.rect.height());
panel.update_container_dims_for_canvas_dims(ctx.canvas.get_window_dims());
panel.recompute_layout(ctx, false);
// Just trigger error if a button is double-defined
panel.get_all_click_actions();
// Let all widgets initially respond to the mouse being somewhere
ctx.no_op_event(true, |ctx| {
if ignore_initial_events {
panel.event(ctx);
} else {
let outcome = panel.event(ctx);
if !matches!(outcome, Outcome::Nothing) {
panic!(
"Initial panel outcome is {}. Consider calling ignore_initial_events",
outcome.describe()
);
}
}
});
panel
}
pub fn aligned(mut self, horiz: HorizontalAlignment, vert: VerticalAlignment) -> PanelBuilder {
self.horiz = horiz;
self.vert = vert;
self
}
pub fn aligned_pair(mut self, pair: (HorizontalAlignment, VerticalAlignment)) -> PanelBuilder {
self.horiz = pair.0;
self.vert = pair.1;View on GitHub (pinned to 0964f29315)