bevyengine/bevy · error · MeshTrianglesError
mesh access error: {0}
Error message
mesh access error: {0} What it means
MeshTrianglesError::MeshAccessError is the #[from] wrapper around MeshAccessError inside triangle extraction. triangles() calls try_attribute and try_indices, which fail with ExtractedToRenderWorld when the mesh's CPU-side vertex/index data has been moved to the RenderWorld because asset_usage excludes MAIN_WORLD.
Source
Thrown at crates/bevy_mesh/src/index.rs:76
/// * [`PrimitiveTopology::LineList`](super::PrimitiveTopology::LineList), but the indices are not in chunks of 2.
#[error("Indices weren't in chunks according to topology")]
AbruptIndicesEnd,
#[error("Mesh access error: {0}")]
MeshAccessError(#[from] MeshAccessError),
}
/// An error that occurred while trying to extract a collection of triangles from a [`Mesh`](super::Mesh).
#[derive(Debug, Error)]
pub enum MeshTrianglesError {
#[error("Source mesh does not have primitive topology TriangleList or TriangleStrip")]
WrongTopology,
#[error("Source mesh position data is not Float32x3")]
PositionsFormat,
#[error("Face index data references vertices that do not exist")]
BadIndices,
#[error("mesh access error: {0}")]
MeshAccessError(#[from] MeshAccessError),
}
/// An array of indices into the [`VertexAttributeValues`](super::VertexAttributeValues) for a mesh.
///
/// It describes the order in which the vertex attributes should be joined into faces.
#[derive(Debug, Clone, Reflect, PartialEq)]
#[reflect(Clone)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub enum Indices {
U16(Vec<u16>),
U32(Vec<u32>),
}
impl Indices {
/// Returns an iterator over the indices.
pub fn iter(&self) -> impl Iterator<Item = usize> + '_ {
match self {View on GitHub (pinned to 396ca72708)
Solutions
- Set mesh.asset_usage to include RenderAssetUsages::MAIN_WORLD alongside RENDER_WORLD
- Read triangle data before the mesh asset is rendered/extracted
- Keep a separate CPU-side copy of geometry for physics/picking
Example fix
// before mesh.asset_usage = RenderAssetUsages::RENDER_WORLD; let tris: Vec<Triangle3d> = mesh.triangles()?.collect(); // Err(ExtractedToRenderWorld) // after mesh.asset_usage = RenderAssetUsages::MAIN_WORLD | RenderAssetUsages::RENDER_WORLD; let tris: Vec<Triangle3d> = mesh.triangles()?.collect();
Defensive patterns
Strategy: validation
Validate before calling
fn mesh_readable_on_cpu(mesh: &Mesh) -> bool {
mesh.asset_usage.contains(RenderAssetUsages::MAIN_WORLD)
}
if mesh_readable_on_cpu(&mesh) {
let tris: Vec<_> = mesh.triangles()?.collect();
} Try / catch
match mesh.triangles() {
Ok(iter) => { /* use triangles */ }
Err(MeshTrianglesError::MeshAccessError(
MeshAccessError::ExtractedToRenderWorld,
)) => { /* use a CPU-side copy of the geometry instead */ }
Err(other) => { /* topology / format / index errors */ }
} Prevention
- Give physics/picking meshes asset_usage that includes MAIN_WORLD
- Snapshot geometry before the mesh is rendered if it is needed later
- Centralize asset_usage policy instead of setting it per mesh ad hoc
When it happens
Trigger: Calling mesh.triangles() on a mesh whose asset_usage is RenderAssetUsages::RENDER_WORLD only, after the render world has extracted the data.
Common situations: Runtime collision or picking systems reading triangles of memory-optimized meshes; mesh inspection tools running after extraction; assets shared between rendering and CPU physics without MAIN_WORLD.
Related errors
- Mesh access error: {0}
- The mesh vertex/index data has been extracted to the RenderW
- Source mesh does not have primitive topology TriangleList or
- Source mesh position data is not Float32x3
- Face index data references vertices that do not exist
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/29ebfc292da72df8.
Report an issue: GitHub.