bevyengine/bevy · error · MeshAttributeCompressionError

Vertex attribute {0:?} must not be empty

Error message

Vertex attribute {0:?} must not be empty

What it means

MeshAttributeCompressionError::EmptyAttribute is thrown when the vertex attribute targeted for compression/quantization exists in the mesh but has no vertex data (zero vertices or an empty buffer). The library refuses to compress an attribute it cannot read any values from.

Source

Thrown at crates/bevy_mesh/src/mesh.rs:3179

                            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 compressing/quantizing mesh vertex attributes.
#[derive(Error, Debug, Clone)]
pub enum MeshAttributeCompressionError {
    #[error("Vertex attribute {0:?} doesn't exist")]
    MissingAttribute(MeshVertexAttributeId),
    #[error("Vertex attribute {0:?} must not be empty")]
    EmptyAttribute(MeshVertexAttribute),
    #[error(
        "Vertex attribute {attr:?} must have format {expected:?} before compressing/quantizing"
    )]
    UnsupportedAttributeForCompression {
        attr: MeshVertexAttribute,
        expected: VertexFormat,
    },
    #[error("Vertex attribute {attr:?} must have format `Float32`, `Float32x2` or `Float32x4` before quantizing")]
    UnsupportedAttributeForQuantizing { attr: MeshVertexAttribute },
}

/// 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}")]

View on GitHub (pinned to 8d743eb7dc)

Solutions

  1. Populate the attribute's vertex data (set via insert_attribute or with the appropriate setter) before compressing
  2. Check the attribute length before compressing: only call compress_attribute when mesh.attribute_len(id) > 0 (or attribute(id).count() > 0)
  3. Skip compression for degenerate/empty meshes in your asset-processing pipeline

Example fix

// before
mesh.quantize_attribute(Mesh::ATTRIBUTE_POSITION.id);
// after
if mesh.attribute_len(Mesh::ATTRIBUTE_POSITION.id) > 0 {
    mesh.quantize_attribute(Mesh::ATTRIBUTE_POSITION.id);
}
Defensive patterns

Strategy: validation

Validate before calling

fn attr_non_empty(mesh: &Mesh, id: MeshVertexAttributeId) -> bool {
    mesh.attribute(id).map(|a| a.count()) > Some(0)
}

Try / catch

match mesh.compress_attribute(id) {
    Err(MeshAttributeCompressionError::EmptyAttribute(attr)) => {
        info!("attribute {:?} empty; nothing to compress", attr);
    }
    other => other.map(|_| ()),
}

Prevention

When it happens

Trigger: Calling Mesh::compress_attribute / quantize_attribute on a mesh whose attribute buffer is empty — e.g. a mesh created and insert_attribute called with no vertices, or all vertices removed before compression.

Common situations: Building a Mesh procedurally and compressing before populating vertices; a degenerate mesh with 0 vertices produced by upstream generation code; meshes whose attribute vectors were cleared by earlier processing.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of bevyengine/bevy@8d743eb7dc (2026-09-13). Data as JSON: /api/errors/71d413843147d9f8. Report an issue: GitHub.