bevyengine/bevy · error · MeshMergeDuplicateVerticesError
Mesh access error: {0}
Error message
Mesh access error: {0} What it means
MeshMergeDuplicateVerticesError::MeshAccessError (crates/bevy_mesh/src/mesh.rs:3018) wraps the MeshAccessError produced while merge_duplicate_vertices reads vertex data. In this code path the NotFound variant is tolerated (missing indices are expected), so the error that actually surfaces is MeshAccessError::ExtractedToRenderWorld: the mesh's RenderAssetUsages excluded MAIN_WORLD, so its vertex/index data was moved to the render world and is no longer readable from the app world.
Source
Thrown at crates/bevy_mesh/src/mesh.rs:3018
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
)]
IncompatiblePrimitiveTopology {
self_primitive_topology: PrimitiveTopology,View on GitHub (pinned to 396ca72708)
Solutions
- Create the mesh with RenderAssetUsages::default() (MAIN_WORLD | RENDER_WORLD) so attributes stay readable
- Do all CPU-side processing (merge_duplicate_vertices, compute_smooth_normals) before spawning/adding the render-world-only mesh
- If the data is already extracted, re-create or re-import the mesh instead of trying to recover it
Example fix
// before: render-world-only mesh let mut mesh = Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::RENDER_WORLD); mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions); // ...after the renderer extracts it: mesh.merge_duplicate_vertices(); // Err(MeshAccessError::ExtractedToRenderWorld) // after: keep data in the main world too let mut mesh = Mesh::new(PrimitiveTopology::TriangleList, RenderAssetUsages::default()); mesh.merge_duplicate_vertices().unwrap();
Defensive patterns
Strategy: validation
Validate before calling
fn cpu_accessible(mesh: &Mesh) -> bool {
mesh.asset_usage().contains(RenderAssetUsages::MAIN_WORLD)
}
if cpu_accessible(&mesh) {
mesh.merge_duplicate_vertices()?;
} Try / catch
if let Err(MeshMergeDuplicateVerticesError::MeshAccessError(
MeshAccessError::ExtractedToRenderWorld,
)) = mesh.merge_duplicate_vertices()
{
// re-create the mesh from source data with RenderAssetUsages::default()
} Prevention
- Only use RenderAssetUsages::RENDER_WORLD for meshes you will never touch on the CPU again
- Finish all CPU-side processing (weld, normals, tangents) before adding the mesh to Assets<Mesh>
- Centralize RenderAssetUsages choice in one factory function so projects stay auditable
When it happens
Trigger: Creating a Mesh with RenderAssetUsages::RENDER_WORLD (main-world data dropped after extraction) and then calling merge_duplicate_vertices() on it after the asset has been prepared/extracted once.
Common situations: Memory-optimized asset pipelines that mark runtime-generated meshes as render-world-only; calling mesh post-processing (welding, normals) from a system that runs after rendering has already consumed the asset.
Related errors
- Mesh access error: {0}
- The number of vertices exceeds u32::MAX
- Index attribute already set.
- unsupported primitive mode
- failed to generate tangents: {0}
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/f1a4b95744610f31.
Report an issue: GitHub.