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
- Only remove buses through remove_bus and never mutate parent_bus/child_buses fields directly.
- Check that the bus handle is valid and still connected before removal (verify via buses.borrow(bus).parent_bus chain).
- 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
- Never mutate bus graph fields directly; use add_bus/remove_bus APIs
- Avoid removing the same bus twice
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Zero duration buffer
- Animation pool must be empty on load!
- Cast to failed!
- An object at index must be returned to a pool it was taken…
- Attempt to spawn an object at pool record with payload!…
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)