FyroxEngine/Fyrox · error

Graph pool must be empty on load!

Error message

Graph pool must be empty on load!

What it means

Graph's Visit implementation requires the node pool to be empty when deserializing (reading) a graph, because loading into a non-empty pool would produce invalid handles and corrupt the scene. It panics if capacity != 0 during read.

Solutions

  1. Load into a fresh Scene/Graph (empty pool) rather than an existing one
  2. Clear the graph (remove all nodes / call clear) before deserializing into it
  3. If merging is needed, load into a temporary Graph and transplant nodes explicitly

Example fix

// before
scene.graph.visit("Graph", &mut visitor)?; // graph still has nodes
// after
let mut scene = Scene::new(); // fresh, empty pool
scene.graph.visit("Graph", &mut visitor)?;
Defensive patterns

Strategy: validation

Validate before calling

assert_eq!(graph.pool.get_capacity(), 0, "graph must be empty before loading");

Prevention

When it happens

Trigger: Calling visitor.load / Graph::visit on a Graph whose pool already contains nodes — e.g. loading a saved scene into an existing scene instead of a fresh one.

Common situations: Deserializing a save game into an already-populated scene; reusing a Scene/Graph object for multiple loads; calling load twice on the same graph.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at fyrox-impl/src/scene/graph/mod.rs:1999

    #[inline]
    fn index(&self, index: Handle<T>) -> &Self::Output {
        self.try_get(index).unwrap()
    }
}

impl<T: ObjectOrVariant<Node>> IndexMut<Handle<T>> for Graph {
    #[inline]
    fn index_mut(&mut self, index: Handle<T>) -> &mut Self::Output {
        self.try_get_mut(index).unwrap()
    }
}

impl Visit for Graph {
    fn visit(&mut self, name: &str, visitor: &mut Visitor) -> VisitResult {
        // Pool must be empty, otherwise handles will be invalid and everything will blow up.
        if visitor.is_reading() && self.pool.get_capacity() != 0 {
            panic!("Graph pool must be empty on load!")
        }

        let mut region = visitor.enter_region(name)?;

        self.root.visit("Root", &mut region)?;
        self.pool.visit("Pool", &mut region)?;
        self.sound_context.visit("SoundContext", &mut region)?;
        self.physics.visit("PhysicsWorld", &mut region)?;
        self.physics2d.visit("PhysicsWorld2D", &mut region)?;
        self.lightmap.visit("Lightmap", &mut region)?;

        Log::verify(self.user_data.visit("UserData", &mut region));

        Ok(())
    }
}

impl SceneGraph for Graph {

View on GitHub (pinned to 76c91aad8e)