{"record":{"id":"0f55bcb3395fbccd","repo":"a-b-street/abstreet","slug":"initial-panel-outcome-is-consider-calling-ignore-initial","errorCode":null,"errorMessage":"Initial panel outcome is {}. Consider calling ignore_initial_events","messagePattern":"Initial panel outcome is (.+?)\\. Consider calling ignore_initial_events","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"widgetry/src/widgets/panel.rs","lineNumber":668,"sourceCode":"        // TODO: to support Panel's that can resize their `contents_dims`, we'll need to detangle\n        // this dependency. This might entail decomposing the flexbox calculation to layout first\n        // the inner content, and then potentially a second pass to layout any x/y scrollbars.\n        panel.recompute_layout(ctx, false);\n        panel.contents_dims =\n            ScreenDims::new(panel.top_level.rect.width(), panel.top_level.rect.height());\n        panel.update_container_dims_for_canvas_dims(ctx.canvas.get_window_dims());\n        panel.recompute_layout(ctx, false);\n\n        // Just trigger error if a button is double-defined\n        panel.get_all_click_actions();\n        // Let all widgets initially respond to the mouse being somewhere\n        ctx.no_op_event(true, |ctx| {\n            if ignore_initial_events {\n                panel.event(ctx);\n            } else {\n                let outcome = panel.event(ctx);\n                if !matches!(outcome, Outcome::Nothing) {\n                    panic!(\n                        \"Initial panel outcome is {}. Consider calling ignore_initial_events\",\n                        outcome.describe()\n                    );\n                }\n            }\n        });\n        panel\n    }\n\n    pub fn aligned(mut self, horiz: HorizontalAlignment, vert: VerticalAlignment) -> PanelBuilder {\n        self.horiz = horiz;\n        self.vert = vert;\n        self\n    }\n\n    pub fn aligned_pair(mut self, pair: (HorizontalAlignment, VerticalAlignment)) -> PanelBuilder {\n        self.horiz = pair.0;\n        self.vert = pair.1;","sourceCodeStart":650,"sourceCodeEnd":686,"githubUrl":"https://github.com/a-b-street/abstreet/blob/0964f29315820c91b171b585eb51e300164e9197/widgetry/src/widgets/panel.rs#L650-L686","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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)."],"exampleFix":"// before\nlet panel = Panel::build(ctx, |panel, ctx| { ... });\n// after\nlet panel = Panel::build_custom(ctx, |panel, ctx| { ... }, true /* ignore_initial_events */);","handlingStrategy":"try-catch","validationCode":"// Ensure widgets emit Outcome::Nothing on the first event, or plan to use ignore_initial_events\nlet uses_ignore = true; // decide before building","typeGuard":null,"tryCatchPattern":"// Since this panics (not a Result), avoid it by construction:\nlet panel = Panel::build_custom(ctx, |panel, ctx| { ... }, /* ignore_initial_events */ true);","preventionTips":["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."],"tags":["gui","panic","initialization","widgetry"],"backgroundTag":"invalid-state-transition","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"}