{"record":{"id":"7c4bc2963638efae","repo":"bevyengine/bevy","slug":"missing-attribute-0","errorCode":null,"errorMessage":"Missing attribute \"{0}\"","messagePattern":"Missing attribute \"(.+?)\"","errorType":"exception","errorClass":"MeshAttributeError","httpStatus":null,"severity":"error","filePath":"crates/bevy_mesh/src/skinning.rs","lineNumber":414,"sourceCode":"\n            self.influence_index += 1;\n\n            if joint_weight > 0.0 {\n                return Some(Influence {\n                    vertex_index: self.vertex_index,\n                    joint_index: JointIndex(joint_index),\n                    joint_weight,\n                });\n            }\n        }\n    }\n}\n\n/// Generic error for when a mesh was expected to have a certain attribute with\n/// a certain format.\n#[derive(Copy, Clone, PartialEq, Debug, Error)]\npub enum MeshAttributeError {\n    #[error(\"Missing attribute \\\"{0}\\\"\")]\n    MissingAttribute(&'static str),\n    #[error(\"Attribute \\\"{0}\\\" has unexpected format {1:?}\")]\n    UnexpectedFormat(&'static str, VertexFormat),\n}\n\n// Implements a function that returns a mesh attribute's data or `MeshAttributeError`.\n//\n// ```\n// impl_expect_attribute!(expect_attribute_float32x3, Float32x3, [f32; 3]);\n//\n// let positions: Vec<[f32; 3]> = expect_attribute_float32x3(mesh, Mesh::ATTRIBUTE_POSITION)?;\n// ```\nmacro_rules! impl_expect_attribute {\n    ($name:ident, $value_type:ident, $output_type:ty) => {\n        fn $name<'a>(\n            mesh: &'a Mesh,\n            attribute: MeshVertexAttribute,\n        ) -> Result<&'a Vec<$output_type>, MeshAttributeError> {","sourceCodeStart":396,"sourceCodeEnd":432,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_mesh/src/skinning.rs#L396-L432","documentation":"MeshAttributeError::MissingAttribute is returned by the expect_attribute_* helpers in bevy_mesh::skinning when a mesh lacks an attribute that was expected with a specific format. It surfaces mainly through SkinnedMeshBounds::from_mesh and InfluenceIterator::new, which require Mesh::ATTRIBUTE_POSITION (Float32x3), Mesh::ATTRIBUTE_JOINT_INDEX (Uint16x4) and Mesh::ATTRIBUTE_JOINT_WEIGHT (Float32x4). The message names the missing attribute.","triggerScenarios":"Calling SkinnedMeshBounds::from_mesh on a mesh that has no JOINT_INDEX or JOINT_WEIGHT attribute (e.g. a static mesh), or whose POSITION attribute was never inserted; also any direct use of InfluenceIterator::new on such a mesh.","commonSituations":"Running skinning/bounds systems on meshes imported without skin data; custom meshes built from scratch where skin attributes were forgotten; blending code that copies positions but drops joint attributes; assuming all meshes in a scene are skinned.","solutions":["Insert the missing skin attributes in the exact expected formats: JOINT_INDEX as VertexAttributeValues::Uint16x4 and JOINT_WEIGHT as VertexAttributeValues::Float32x4 (plus POSITION as Float32x3)","Guard the call: only derive SkinnedMeshBounds for meshes that actually carry skin attributes (check mesh.attribute(Mesh::ATTRIBUTE_JOINT_INDEX).is_some())","If the mesh is supposed to be static, skip from_mesh entirely and use mesh.compute_aabb()","Inspect the error's attribute name to see exactly which of the three attributes is absent"],"exampleFix":"// before: mesh without skin data\nlet bounds = SkinnedMeshBounds::from_mesh(&mesh)?; // Err(MissingAttribute(\"JOINT_INDEX\"))\n\n// after: provide the required attributes\nmesh.insert_attribute(Mesh::ATTRIBUTE_POSITION, positions);        // Vec<[f32; 3]>\nmesh.insert_attribute(Mesh::ATTRIBUTE_JOINT_INDEX, joint_indices); // Vec<[u16; 4]>\nmesh.insert_attribute(Mesh::ATTRIBUTE_JOINT_WEIGHT, weights);     // Vec<[f32; 4]>\nlet bounds = SkinnedMeshBounds::from_mesh(&mesh)?;","handlingStrategy":"validation","validationCode":"fn is_skinned_mesh_ready(mesh: &Mesh) -> bool {\n    mesh.attribute(Mesh::ATTRIBUTE_POSITION).is_some()\n        && mesh.attribute(Mesh::ATTRIBUTE_JOINT_INDEX).is_some()\n        && mesh.attribute(Mesh::ATTRIBUTE_JOINT_WEIGHT).is_some()\n}\n\nif is_skinned_mesh_ready(&mesh) {\n    let bounds = SkinnedMeshBounds::from_mesh(&mesh)?;\n}","typeGuard":"fn has_skin_attributes(mesh: &Mesh) -> bool {\n    matches!(mesh.attribute(Mesh::ATTRIBUTE_JOINT_INDEX), Some(VertexAttributeValues::Uint16x4(_)))\n        && matches!(mesh.attribute(Mesh::ATTRIBUTE_JOINT_WEIGHT), Some(VertexAttributeValues::Float32x4(_)))\n}","tryCatchPattern":"match SkinnedMeshBounds::from_mesh(&mesh) {\n    Ok(bounds) => { /* use */ }\n    Err(SkinnedMeshBoundsError::MeshAttributeError(\n        MeshAttributeError::MissingAttribute(name),\n    )) => {\n        warn!(\"skipping bounds for mesh without attribute {name}\");\n    }\n    Err(other) => warn!(\"skinning bounds failed: {other:?}\"),\n}","preventionTips":["Only invoke SkinnedMeshBounds::from_mesh on meshes known to carry skin attributes","Insert JOINT_INDEX as Uint16x4 and JOINT_WEIGHT as Float32x4 whenever you author skinned meshes","Gate systems with a query filter on SkinnedMesh so static meshes never reach this code"],"tags":["bevy","mesh","skinning","attributes","validation"],"backgroundTag":"missing-mesh-attribute","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}