{"record":{"id":"186f2ef2a16c8d08","repo":"linebender/druid","slug":"commands-should-be-dispatched-via-dispatch-cmd","errorCode":null,"errorMessage":"commands should be dispatched via dispatch_cmd","messagePattern":"commands should be dispatched via dispatch_cmd","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"druid/src/win_handler.rs","lineNumber":419,"sourceCode":"                    let event = Event::Command(cmd.clone());\n                    if w.event(&mut self.command_queue, event, &mut self.data, &self.env)\n                        .is_handled()\n                    {\n                        return Handled::Yes;\n                    }\n                }\n            }\n            Target::Auto => {\n                tracing::error!(\"{:?} reached window handler with `Target::Auto`\", cmd);\n            }\n        }\n        Handled::No\n    }\n\n    fn do_window_event(&mut self, source_id: WindowId, event: Event) -> Handled {\n        match event {\n            Event::Command(..) | Event::Internal(InternalEvent::TargetedCommand(..)) => {\n                panic!(\"commands should be dispatched via dispatch_cmd\");\n            }\n            _ => (),\n        }\n\n        // if the event was swallowed by the delegate we consider it handled?\n        let event = match self.delegate_event(source_id, event) {\n            Some(event) => event,\n            None => return Handled::Yes,\n        };\n\n        if let Some(win) = self.windows.get_mut(source_id) {\n            win.event(&mut self.command_queue, event, &mut self.data, &self.env)\n        } else {\n            Handled::No\n        }\n    }\n\n    fn show_context_menu(&mut self, window_id: WindowId, cmd: &Command) {","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/linebender/druid/blob/0f8b1195e4e073f9597f2865299c3d18f8e4005f/druid/src/win_handler.rs#L401-L437","documentation":"druid's AppHandler::do_window_event is the path for ordinary window events only. Command and targeted-command events must travel through `dispatch_cmd`, which routes them to the correct target window/delegate; receiving one here means a command was injected into the wrong dispatch path, so the handler panics to surface the invariant violation.","triggerScenarios":"Delivering `Event::Command` or `Event::Internal(InternalEvent::TargetedCommand(..))` directly into `do_window_event` — typically by calling the window-handler plumbing yourself, custom event loops, or code that bypasses `AppHandler::dispatch_cmd`.","commonSituations":"Custom main-loop or test harnesses pushing events straight to the handler; monkey-patched or forked druid code that forwards all window events uniformly; re-injecting a captured Event object back into the handler.","solutions":["Route commands through `AppHandler::dispatch_cmd` (or higher-level `WidgetExt::submit_command` / `EventCtx::submit_command`) instead of feeding them into `do_window_event`","In custom dispatch code, match on the event kind and forward Command variants to dispatch_cmd, passing only other events to do_window_event","If you only hold a generic Event, inspect it: commands should never be re-dispatched manually; use the command's WindowId target with dispatch_cmd"],"exampleFix":"// before\nhandler.do_window_event(window_id, Event::Command(cmd));\n// after\nhandler.dispatch_cmd(window_id, cmd); // or ctx.submit_command(cmd)","handlingStrategy":"validation","validationCode":"// Route by event kind before touching do_window_event\nmatch &event {\n    Event::Command(_) | Event::Internal(InternalEvent::TargetedCommand(_)) => handler.dispatch_cmd(window_id, event.unwrap_cmd()),\n    _ => handler.do_window_event(window_id, event),\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use ctx.submit_command / dispatch_cmd for commands","Never forward raw Event values into do_window_event in custom loops","In tests, use the same dispatch entry points the framework uses"],"tags":["druid","rust","gui","commands","dispatch","panic"],"backgroundTag":"invalid-state-transition","analyzedSha":"0f8b1195e4e073f9597f2865299c3d18f8e4005f","analyzedAt":"2026-09-10T14:27:34.582Z","contentChangedAt":"2026-09-10T14:27:34.582Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}