FyroxEngine/Fyrox · error

Malformed bus graph!

Error message

Malformed bus graph!

What it means

remove_bus detaches a bus from the sound bus graph by removing its handle from its parent's child_buses list. The expect fires when the child handle cannot be found in the parent's list, meaning the bus graph is inconsistent (corrupted invariant). This indicates an internal bug or misuse that broke parent/child bookkeeping.

Solutions

  1. Only remove buses through remove_bus and never mutate parent_bus/child_buses fields directly.
  2. Check that the bus handle is valid and still connected before removal (verify via buses.borrow(bus).parent_bus chain).
  3. Guard against double removal — ensure remove_bus is called once per bus handle.

Example fix

// before
bus_graph.buses.borrow_mut(bus).parent_bus = other; // corrupts graph
bus_graph.remove_bus(bus); // panics
// after
bus_graph.remove_bus(bus);
bus_graph.add_bus(other, bus); // use API to rewire
Defensive patterns

Strategy: validation

Validate before calling

let parent = bus_graph.buses.borrow(bus).parent_bus;
assert!(bus_graph.buses.borrow(parent).child_buses.iter().any(|h| *h == bus));

Prevention

When it happens

Trigger: Calling remove_bus on a bus whose parent_bus index is stale or whose handle was never (or no longer) registered as a child of its declared parent — e.g. after manually mutating bus.parent_bus without updating the old parent's child list, or double-removing a bus.

Common situations: Manually rewiring buses by writing parent_bus directly; removing a bus twice; restoring buses from a snapshot inconsistently; engine version changes altering bus graph layout.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10). Data as JSON: /api/errors/43d4cd2c103c7cc4. Report an issue: GitHub.

Appendix: source

Thrown at fyrox-sound/src/bus.rs:398

                Some(bus.input_buffer())
            } else {
                None
            }
        })
    }

    /// Removes an audio bus at the given handle.
    pub fn remove_bus(&mut self, handle: Handle<AudioBus>) -> AudioBus {
        assert_ne!(handle, self.root);

        let bus = self.buses.free(handle);
        let parent_bus = &mut self.buses[bus.parent_bus];

        let position = parent_bus
            .child_buses
            .iter()
            .position(|h| *h == handle)
            .expect("Malformed bus graph!");
        parent_bus.child_buses.remove(position);

        bus
    }

    /// Returns a handle of the primary audio bus. Primary bus outputs its samples directly to an audio playback
    /// device.
    pub fn primary_bus_handle(&self) -> Handle<AudioBus> {
        self.root
    }

    /// Returns a reference to the primary audio bus.
    pub fn primary_bus_ref(&self) -> &AudioBus {
        &self.buses[self.root]
    }

    /// Returns a reference to the primary audio bus.
    pub fn primary_bus_mut(&mut self) -> &mut AudioBus {

View on GitHub (pinned to 76c91aad8e)