iced-rs/iced · error

Send event

Error message

Send event

What it means

The winit runtime's event pump asserts that start_send on a channel to the application's event processor succeeds. This fails only when the channel's receiver has been dropped - i.e. the other half of the Proxy/pump pipeline shut down - which iced treats as an unrecoverable internal state violation during process_event.

Source

Thrown at winit/src/lib.rs:269

        fn about_to_wait(&mut self, event_loop: &winit::event_loop::ActiveEventLoop) {
            self.process_event(
                event_loop,
                Event::EventLoopAwakened(winit::event::Event::AboutToWait),
            );
        }
    }

    impl<Message> Runner<Message> {
        fn process_event(
            &mut self,
            event_loop: &winit::event_loop::ActiveEventLoop,
            event: Event<Action<Message>>,
        ) {
            if event_loop.exiting() {
                return;
            }

            self.sender.start_send(event).expect("Send event");

            loop {
                let poll = self.instance.as_mut().poll(&mut self.context);

                match poll {
                    task::Poll::Pending => match self.receiver.try_recv() {
                        Ok(control) => match control {
                            Control::ChangeFlow(flow) => {
                                use winit::event_loop::ControlFlow;

                                match (event_loop.control_flow(), flow) {
                                    (
                                        ControlFlow::WaitUntil(current),
                                        ControlFlow::WaitUntil(new),
                                    ) if current < new => {}
                                    (ControlFlow::WaitUntil(target), ControlFlow::Wait)
                                        if target > Instant::now() => {}
                                    _ => {

View on GitHub (pinned to d146509d89)

Solutions

  1. Avoid sending events/messages after initiating application exit; guard async tasks/subscriptions with a cancellation flag checked on completion.
  2. Check that tasks spawned via the Proxy don't outlive the program (join/abort them on shutdown).
  3. Upgrade iced - teardown races in the winit runtime have been fixed across releases.
  4. If reproducible, capture the exact sequence (exit + pending event) and restructure so the exit is processed via a message rather than directly stopping the loop.

Example fix

// before
self.sender.start_send(event).expect("Send event");
// after (caller-side guard before exiting)
if !exiting {
    proxy.send_event(ev).ok();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// before sending from a task, check the program is still running
if app_is_running.load(std::sync::atomic::Ordering::Relaxed) {
    proxy.send_event(ev).ok();
}

Try / catch

// treat send failure as shutdown, not a crash
match sender.start_send(event) {
    Ok(()) => { /* continue */ }
    Err(_) => return, // receiver gone: event loop is shutting down
}

Prevention

When it happens

Trigger: An event (window_event, user_event, new_events, etc.) is dispatched while the receiving side of the mpsc channel (self.receiver's owner) has already been dropped, typically after shutdown/exit began but before the event loop stopped, or from a Proxy send racing application teardown.

Common situations: Sending messages from a subscription/task right as the window closes; programmatic exit() from user code followed by in-flight events; multi-window setups where one window's close tears down the pump while events still arrive.

Related errors


AI-assisted analysis of iced-rs/iced@d146509d89 (2026-09-11). Data as JSON: /api/errors/e1e1a495a27a5521. Report an issue: GitHub.