bevyengine/bevy · critical

Bin key not present

Error message

Bin key not present

What it means

remove() on the multidrawable bins (mod.rs:610) expects the bin_key to exist in bin_key_to_bin_index; the panic fires when an entity is removed under a key whose bin was already freed or never created. The documented contract is 'The given entity must be present in that bin', so the caller's key must match the one used at insertion.

Source

Thrown at crates/bevy_render/src/render_phase/mod.rs:609

                .insert(bin, main_entity, input_uniform_index, bin_index);

        self.instance_count += 1;
        debug_assert_eq!(
            binned_mesh_instance_index.0 as usize,
            self.binned_mesh_instance_index_to_entity.len()
        );
        self.binned_mesh_instance_index_to_entity.push(main_entity);
    }

    /// Removes the given entity from the bin with the given key.
    ///
    /// The given entity must be present in that bin.
    fn remove(&mut self, main_entity: MainEntity, bin_key: &BPI::BinKey) {
        // Fetch the bin index.
        let bin_index = *self
            .bin_key_to_bin_index
            .get(bin_key)
            .expect("Bin key not present");
        let bin = self.bins[bin_index.0 as usize].as_mut().unwrap();

        let instance_removal_result = self.gpu_buffers.remove(bin, bin_index, main_entity);

        // Because the instance is removed with `swap_remove`, we have two cases
        // to consider.
        match instance_removal_result.displaced_instance {
            // Case 1: The instance was removed from the middle of the array. In
            // that case, we have a *displaced entity* that was swapped in to
            // fill the hole. We need to update the table that maps binned mesh
            // instance index to entity and the reverse table that maps entity
            // to binned mesh instance index.
            Some((displaced_instance_index, displaced_instance)) => {
                debug_assert_eq!(
                    displaced_instance_index.0 + 1,
                    self.binned_mesh_instance_index_to_entity.len() as u32
                );
                let displaced_entity = self.binned_mesh_instance_index_to_entity.pop().expect(

View on GitHub (pinned to 221e52ae32)

Solutions

  1. Avoid changing bin-key-relevant mesh/material properties concurrently with entity removal in the same frame.
  2. Ensure entities are removed from the phase once, through one path.
  3. Upgrade Bevy to pick up bin lifecycle fixes.
  4. Report upstream with a backtrace if no custom removal code is involved.
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Removing an entity whose bin key (binning parameters derived from mesh/material state) no longer maps to an existing bin - the key changed between insertion and removal, or the bin was emptied/freed while the entity was still slated for removal, or the entity was already removed.

Common situations: Mutating mesh or material properties that feed the bin key in the same frame the entity is removed; double-removal through multiple code paths; engine bugs in the multidraw path across Bevy versions.

Related errors


AI-assisted analysis of bevyengine/bevy@221e52ae32 (2026-08-20). Data as JSON: /api/errors/37951fbd5de38514. Report an issue: GitHub.