bevyengine/bevy · error · MeshToMeshletMeshConversionError
Mesh has no indices
Error message
Mesh has no indices
What it means
`validate_input_mesh` in crates/bevy_pbr/src/meshlet/from_mesh.rs:274 requires `mesh.indices()` to return `Some(Indices::U16(_))` or `Some(Indices::U32(_))` before `MeshletMesh::from_mesh` can run. Meshletization works on triangle index lists, so a mesh with only a vertex buffer (no index buffer) is rejected with `MeshToMeshletMeshConversionError::MeshMissingIndices`.
Source
Thrown at crates/bevy_pbr/src/meshlet/from_mesh.rs:1100
// https://www.w3.org/TR/WGSL/#pack2x16snorm-builtin
fn pack2x16snorm(v: Vec2) -> u32 {
let v = v.clamp(Vec2::NEG_ONE, Vec2::ONE);
let v = (v * 32767.0 + 0.5).floor().as_i16vec2();
bytemuck::cast(v)
}
/// An error produced by [`MeshletMesh::from_mesh`].
#[derive(Error, Debug)]
pub enum MeshToMeshletMeshConversionError {
#[error("Mesh primitive topology is not TriangleList")]
WrongMeshPrimitiveTopology,
#[error("Mesh vertex attributes must be {required:?}, but got {provided:?}")]
WrongMeshVertexAttributes {
required: [MeshVertexAttribute; 3],
provided: Vec<MeshVertexAttribute>,
},
#[error("Mesh has no indices")]
MeshMissingIndices,
}
View on GitHub (pinned to 396ca72708)
Solutions
- Check `mesh.indices()` in a debug assert before converting
- If you only have vertices, insert a sequential index list: `mesh.insert_indices(Indices::U32((0..vertex_count as u32).collect()))`
- If you have triangle data elsewhere, build and insert the index buffer before `from_mesh`
Example fix
// before: vertex-only mesh -> MeshMissingIndices let mut mesh = Mesh::new(PrimitiveTopology::TriangleList); mesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions); // after: add an index buffer let vertex_count = positions.len() as u32; mesh.insert_indices(Indices::U32((0..vertex_count).collect()));
Defensive patterns
Strategy: validation
Validate before calling
if mesh.indices().is_none() {
let count = mesh.count_vertices();
mesh.insert_indices(Indices::U32((0..count as u32).collect()));
}
let meshlet = MeshletMesh::from_mesh(mesh, &viewer)?; Try / catch
match MeshletMesh::from_mesh(mesh, &viewer) {
Err(MeshToMeshletMeshConversionError::MeshMissingIndices) => {
warn!(?asset_path, "mesh has no indices; skipping meshlet conversion");
// fall back to rendering the plain Mesh
}
other => other?,
} Prevention
- Assert `mesh.indices().is_some()` in mesh-builder unit tests
- Centralize mesh construction so every builder ends with insert_indices
- Treat a vertex-only mesh as a bug: add a debug_assert in your asset pipeline
When it happens
Trigger: Calling `MeshletMesh::from_mesh` on a mesh built without `mesh.insert_indices(...)` — custom procedural geometry where only `insert_attribute(Mesh::ATTRIBUTE_POSITION, ...)` was called, or a triangle soup that never got an index list.
Common situations: Hand-rolled mesh builders (terrain chunks, procedural geometry loaders) that skip the index step; meshes converted from formats that store only vertex data; refactors that drop the `insert_indices` call.
Related errors
- Mesh vertex attributes must be {required:?}, but got {provid
- Color compression flag must be `COMPRESS_COLOR_FLOAT16` or `
- cannot convert VertexAttributeValues::{variant} to {into}
- Mesh winding inversion does not work for primitive topology
- Indices weren't in chunks according to topology
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/7acedad420563c5a.
Report an issue: GitHub.