FyroxEngine/Fyrox · error
A node with existing name
Error message
A node with existing name {} was found during the load of {} resource! Do **NOT IGNORE** this message, please fix names in your model, otherwise engine won't be able to correctly restore data from your resource! What it means
When loading a glTF scene, Fyrox resolves duplicate node names by renaming, then verifies no collisions remain via resolve_name_conflicts. If two scene nodes still share a name, the engine cannot reliably map saved/animated data back to nodes, so it logs this emphatic error naming the duplicated node and the resource path.
Solutions
- Fix duplicate node names in the source model (DCC tool or glTF JSON): give every node a unique name and re-export.
- Check for nodes with empty names in the glTF and name them explicitly before export.
- Do not ignore the message — downstream save/restore of node data (animations, prefabs) will corrupt or bind to the wrong nodes.
Example fix
// before (glTF nodes)
{"name":"Arm"}, {"name":"Arm"}
// after
{"name":"Arm_L"}, {"name":"Arm_R"} Defensive patterns
Strategy: validation
Validate before calling
// Before loading, verify node names in the glTF JSON are unique:
fn names_unique(nodes: &[serde_json::Value]) -> bool {
let names: Vec<_> = nodes.iter()
.map(|n| n["name"].as_str().unwrap_or("").to_string())
.collect();
names.iter().all(|n| !n.is_empty())
&& names.len() == names.iter().collect::<std::collections::HashSet<_>>().len()
} Prevention
- Enforce unique, non-empty node names in your DCC tool's export checklist.
- Never merge scenes without renaming colliding nodes.
- Treat this log as blocking: duplicate names corrupt saved data mapping.
When it happens
Trigger: Loading a glTF/GLB resource where, after conflict resolution, graph.linear_iter() still finds two nodes with the same name — e.g. duplicate node names in the source file that the resolver failed to disambiguate (names differing only by characters normalized away, or empty names).
Common situations: Hand-authored or merged glTF files where two nodes share identical names; assets concatenated from multiple scenes; exporters that emit empty or default names for multiple nodes.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- Failed to import animation
- glTF material failed to import. Reason
- : Model has triangles with repeated vertices
- : Mesh has a triangle with a zero-length edge!
- : Mesh has a triangle with edge length
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/7bbe4ef199af3cfa.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/resource/gltf/node_names.rs:65
/// If the nodes have parents with the same names, then grandparent names may
/// be used if the grandparents have different names. If the whole ancestry
/// of the nodes is searched without finding ancestors with distinct names
/// then the nodes are not renamed.
///
/// If after the whole procedure there is found to still be nodes with duplicate names,
/// an error is logged to alert the user to the problem.
pub fn resolve_name_conflicts(path: &Path, graph: &mut Graph) {
let node_sets: Vec<Vec<Handle<Node>>> = build_node_sets_from_graph(graph);
for nodes in node_sets {
if nodes.len() > 1 {
resolve_conflict(nodes, graph);
}
}
// Check if conflicts have actually been resolved.
let mut name_set: FxHashSet<&str> = FxHashSet::default();
for node in graph.linear_iter() {
if !name_set.insert(node.name()) {
Log::err(format!(
"A node with existing name {} was found during the load of {} resource! \
Do **NOT IGNORE** this message, please fix names in your model, otherwise \
engine won't be able to correctly restore data from your resource!",
node.name(),
path.display()
));
}
}
}
fn build_node_sets_from_graph(graph: &Graph) -> Vec<Vec<Handle<Node>>> {
let mut name_map: FxHashMap<&str, Vec<Handle<Node>>> = FxHashMap::default();
for (handle, node) in graph.pair_iter() {
let name = node.name();
let list = name_map
.entry(name)
.or_insert_with(|| Vec::with_capacity(1));
list.push(handle);View on GitHub (pinned to 76c91aad8e)