bevyengine/bevy · error

mapping should exist from connection

Error message

mapping should exist from connection

What it means

This expect() panics inside bevy_gilrs's gilrs_event_system when a Disconnected event arrives for a gilrs gamepad id that has no entry in the GilrsGamepads.id_to_entity map. The map is populated at startup (gilrs_event_startup_system) and on Connected events; the Disconnected branch assumes the mapping exists. A missing mapping therefore indicates an internal invariant break: the device generated a disconnect the engine never saw a connection for (or the map was cleared).

Source

Thrown at crates/bevy_gilrs/src/gilrs_system.rs:76

                    });

                    let event = GamepadConnectionEvent::new(
                        entity,
                        GamepadConnection::Connected {
                            name: pad.name().to_string(),
                            vendor_id: pad.vendor_id(),
                            product_id: pad.product_id(),
                        },
                    );
                    events.write(event.clone().into());
                    connection_events.write(event);
                }
                EventType::Disconnected => {
                    let gamepad = gamepads
                        .id_to_entity
                        .get(&gilrs_event.id)
                        .copied()
                        .expect("mapping should exist from connection");
                    let event =
                        GamepadConnectionEvent::new(gamepad, GamepadConnection::Disconnected);
                    events.write(event.clone().into());
                    connection_events.write(event);
                }
                EventType::ButtonChanged(gilrs_button, raw_value, code) => {
                    let button = convert_button(gilrs_button, code);
                    let gamepad = gamepads
                        .id_to_entity
                        .get(&gilrs_event.id)
                        .copied()
                        .expect("mapping should exist from connection");
                    events.write(
                        RawGamepadButtonChangedEvent::new(gamepad, button, raw_value).into(),
                    );
                    button_events.write(RawGamepadButtonChangedEvent::new(
                        gamepad, button, raw_value,
                    ));

View on GitHub (pinned to 396ca72708)

Solutions

  1. Add GilrsPlugin during App construction (before startup), so gilrs_event_startup_system maps all initially connected pads.
  2. Ensure GilrsGamepads / Gilrs resources are never cleared or replaced by user code or world-clearing routines.
  3. Update Bevy — gaps in gilrs id mapping on disconnect are engine bugs; check the issue tracker for your version and upgrade.
  4. If it reproduces deterministically with specific hardware, file a bevy_gilrs issue with the controller model and OS.

Example fix

// before
app.add_systems(Startup, gameplay_setup);
app.add_plugins(GilrsPlugin); // added after startup ran once => unmapped pads can panic

// after
app.add_plugins(GilrsPlugin); // registers startup mapping for connected pads
app.add_systems(Startup, gameplay_setup);
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: A gamepad disconnects whose Connected event was never processed through this system (e.g. GilrsPlugin added after startup systems ran, so gilrs_event_startup_system never mapped existing pads); the GilrsGamepads resource was cleared/reset mid-run; driver/OS quirks emitting disconnects for unknown device ids (Bluetooth controllers, hot-swap during sleep/wake).

Common situations: Adding GilrsPlugin at runtime after app startup instead of before; tests that inject gilrs events without the startup system; OS sleep/resume with a wireless controller; platform driver bugs replaying stale ids.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/cdc590ed1bbe542e. Report an issue: GitHub.