bevyengine/bevy · error · MeshMergeDuplicateVerticesError
Index attribute already set.
Error message
Index attribute already set.
What it means
MeshMergeDuplicateVerticesError::IndicesAlreadySet (crates/bevy_mesh/src/mesh.rs:3016), returned by Mesh::merge_duplicate_vertices when self.try_indices() finds an existing index buffer. The function's contract is to CREATE indices from a non-indexed vertex soup; an already-indexed mesh violates that precondition, so it refuses instead of overwriting valid topology.
Source
Thrown at crates/bevy_mesh/src/mesh.rs:3016
warn!(
"Deserialized mesh contains custom vertex attribute {attribute:?} that \
was not specified with `MeshDeserializer::add_custom_vertex_attribute`. Ignoring."
);
return None;
};
Some((id, data))
})
.collect()),
indices: serialized_mesh.indices.into(),
..Mesh::new(serialized_mesh.primitive_topology, RenderAssetUsages::default())
}
}
}
/// Error that can occur when calling [`Mesh::merge_duplicate_vertices`]
#[derive(Error, Debug, Clone)]
pub enum MeshMergeDuplicateVerticesError {
#[error("Index attribute already set.")]
IndicesAlreadySet,
#[error("Mesh access error: {0}")]
MeshAccessError(#[from] MeshAccessError),
}
/// Error that can occur when calling [`Mesh::merge`].
#[derive(Error, Debug, Clone)]
pub enum MeshMergeError {
#[error("Incompatible vertex attribute types: {} and {}", self_attribute.name, other_attribute.map(|a| a.name).unwrap_or("None"))]
IncompatibleVertexAttributes {
self_attribute: MeshVertexAttribute,
other_attribute: Option<MeshVertexAttribute>,
},
#[error(
"Incompatible primitive topologies: {:?} and {:?}",
self_primitive_topology,
other_primitive_topology
)]View on GitHub (pinned to 396ca72708)
Solutions
- If you really want to rebuild indices, drop the existing buffer first: mesh.remove_indices(), then merge_duplicate_vertices()
- For flat shading of indexed geometry use the documented recipe: mesh.duplicate_vertices() then mesh.compute_flat_normals()
- For smooth shading keep the existing indices and call compute_smooth_normals() instead
Example fix
// before: Sphere builder already inserted indices let mut mesh = Sphere::new(1.0).mesh().build(); mesh.merge_duplicate_vertices(); // Err(IndicesAlreadySet) // after: drop old indices, then dedupe let mut mesh = Sphere::new(1.0).mesh().build(); mesh.remove_indices(); mesh.merge_duplicate_vertices().unwrap();
Defensive patterns
Strategy: try-catch
Validate before calling
if mesh.indices().is_none() {
mesh.merge_duplicate_vertices()?;
} else {
// already indexed: nothing to dedupe, or remove_indices() first if rebuilding
} Type guard
fn is_unindexed(mesh: &Mesh) -> bool {
mesh.indices().is_none()
} Try / catch
match mesh.merge_duplicate_vertices() {
Ok(()) => {}
Err(MeshMergeDuplicateVerticesError::IndicesAlreadySet) => {
// decide: keep existing topology, or mesh.remove_indices() and retry
}
Err(MeshMergeDuplicateVerticesError::MeshAccessError(e)) => {
bevy::log::error!("mesh data unavailable: {e}");
}
} Prevention
- Remember merge_duplicate_vertices is for NON-indexed meshes only
- Gate the call behind mesh.indices().is_none()
- Keep the documented recipes straight: smooth normals need indices, flat normals need duplicate_vertices
When it happens
Trigger: Calling merge_duplicate_vertices() on any mesh that already has indices set: meshes from Bevy primitive builders (Sphere, Torus, ... all insert Indices::U32/U16), imported glTF geometry (indexed by nature), or a mesh where you previously called insert_indices/with_inserted_indices or an earlier successful merge_duplicate_vertices.
Common situations: Developer welds an imported indexed mesh to smooth seams and calls merge_duplicate_vertices directly; mixing up the documented normal-generation recipes (compute_smooth_normals wants indexed geometry, compute_flat_normals wants non-indexed) and reaching for the wrong helper.
Related errors
- Indices weren't in chunks according to topology
- Face index data references vertices that do not exist
- The number of vertices exceeds u32::MAX
- Mesh access error: {0}
- missing indices
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/26fd61a39108fc65.
Report an issue: GitHub.