FyroxEngine/Fyrox · error
The handle must be valid
Error message
The handle must be valid
What it means
Graph::add_node (internal node insertion) spawns the node at a pre-reserved handle. The handle was expected to be reserved beforehand (via generate_free_handle/is_valid_handle), so spawning should always succeed; if the pool reports the handle invalid, an internal invariant is broken and the code panics.
Solutions
- Only use handles obtained from graph.generate_free_handle() (or public add_node APIs that reserve internally)
- Reserve a fresh handle with take_reserve if you need to link children by known handle
- Do not persist and reuse handles across different Graph instances
Example fix
// before let handle = Handle::new(42, 0); graph.add_node(node, handle); // after let handle = graph.generate_free_handle(); graph.add_node(node, handle);
Defensive patterns
Strategy: validation
Validate before calling
// reserve handles only from the same graph let handle = graph.generate_free_handle();
Try / catch
// invariant violation; use public add_node APIs that reserve handles internally instead of catch
Prevention
- Only use handles from generate_free_handle or public node-creation APIs
- Never deserialize raw handle indices into a fresh Graph
- Prefer add_node returning its own handle over pre-computed handles
When it happens
Trigger: Passing a handle that was never reserved from this graph's pool, or reusing a handle already consumed; typically only reachable through misuse of generate_free_handle/add_node pairs rather than public add_node with fresh handles.
Common situations: Custom graph-copy/deserialization code generating handles manually; handles serialized from an older graph reused in a new graph instance.
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
- Attempt to spawn an object at pool record with payload!…
- Attempt to replace object in pool using dangling handle!…
- Graph pool must be empty on load!
- The handle must be valid!
- Animation pool must be empty on load!
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/7b01bf88b9b2ff39.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-graph/src/lib.rs:1956
}
fn add_node(&mut self, node: Self::NodeWrapper) -> Handle<Self::NodeWrapper> {
let handle = self.nodes.next_free_handle();
self.add_node_at_handle(node, handle);
handle
}
fn add_node_at_handle(
&mut self,
mut node: Self::NodeWrapper,
handle: Handle<Self::NodeWrapper>,
) {
let children = node.children.clone();
node.children.clear();
let handle = self
.nodes
.spawn_at_handle(handle, node)
.expect("The handle must be valid");
if self.root.is_none() {
self.root = handle;
} else {
self.link_nodes(handle, self.root);
}
for child in children {
self.link_nodes(child, handle);
}
let node = &mut self.nodes[handle];
node.self_handle = handle;
}
fn remove_node(&mut self, node_handle: Handle<impl ObjectOrVariant<Self::NodeWrapper>>) {
let node_handle = node_handle.to_base();
self.isolate_node(node_handle);View on GitHub (pinned to 76c91aad8e)