{"record":{"id":"336e77853ec9181e","repo":"bevyengine/bevy","slug":"the-0-vertex-attribute-should-have-1-forma","errorCode":null,"errorMessage":"the '{0}' vertex attribute should have {1:?} format","messagePattern":"the '(.+?)' vertex attribute should have (.+?) format","errorType":"exception","errorClass":"GenerateTangentsError","httpStatus":null,"severity":"error","filePath":"crates/bevy_mesh/src/mikktspace.rs","lineNumber":71,"sourceCode":"        tangent_space: Option<bevy_mikktspace::TangentSpace>,\n        face: usize,\n        vert: usize,\n    ) {\n        let idx = self.index(face, vert);\n        self.tangents[idx] = tangent_space.unwrap_or_default().tangent_encoded();\n    }\n}\n\n#[derive(Error, Debug)]\n/// Failed to generate tangents for the mesh.\npub enum GenerateTangentsError {\n    #[error(\"cannot generate tangents for {0:?}\")]\n    UnsupportedTopology(PrimitiveTopology),\n    #[error(\"missing indices\")]\n    MissingIndices,\n    #[error(\"missing vertex attributes '{0}'\")]\n    MissingVertexAttribute(&'static str),\n    #[error(\"the '{0}' vertex attribute should have {1:?} format\")]\n    InvalidVertexAttributeFormat(&'static str, VertexFormat),\n    #[error(\"mesh not suitable for tangent generation\")]\n    MikktspaceError(#[from] bevy_mikktspace::GenerateTangentSpaceError),\n    #[error(\"Mesh access error: {0}\")]\n    MeshAccessError(#[from] MeshAccessError),\n}\n\npub(crate) fn generate_tangents_for_mesh(\n    mesh: &Mesh,\n) -> Result<Vec<[f32; 4]>, GenerateTangentsError> {\n    match mesh.primitive_topology() {\n        PrimitiveTopology::TriangleList => {}\n        other => return Err(GenerateTangentsError::UnsupportedTopology(other)),\n    };\n\n    let positions = mesh.try_attribute_option(Mesh::ATTRIBUTE_POSITION)?.ok_or(\n        GenerateTangentsError::MissingVertexAttribute(Mesh::ATTRIBUTE_POSITION.name),\n    )?;","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_mesh/src/mikktspace.rs#L53-L89","documentation":"GenerateTangentsError::InvalidVertexAttributeFormat (crates/bevy_mesh/src/mikktspace.rs:71), returned by Mesh::compute_tangents when a required attribute exists but with the wrong VertexFormat. Mikktspace consumes positions and normals as Float32x3 and UVs as Float32x2; anything else (Float32x2 positions, Float32x3 UVs, packed formats) is rejected with the attribute name and the format it found.","triggerScenarios":"Calling compute_tangents() on a mesh where ATTRIBUTE_POSITION/ATTRIBUTE_NORMAL is not Float32x3 or ATTRIBUTE_UV_0 is not Float32x2 — e.g. UVs inserted as [f32; 3] from a texture pipeline, normals carried as Snorm8x4 after compression.","commonSituations":"Assets imported from engines that use vec3 UVs (w coordinate for projective texturing); vertex-compression passes that repack normals; custom attributes accidentally reusing a standard attribute id with an exotic format.","solutions":["Read the error payload: '{0}' names the attribute, '{1:?}' the offending format","Convert and re-insert the attribute with the required format (positions/normals -> Vec<[f32; 3]>, UVs -> Vec<[f32; 2]>)","Keep compression/packing passes out of the pre-tangent stage; compress after tangents exist"],"exampleFix":"// before: UVs stored as float3\nmesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vec![[u, v, 0.0f32]; n]);\nmesh.compute_tangents(); // Err(InvalidVertexAttributeFormat(\"Vertex_Uv\", Float32x3))\n\n// after: UVs as float2\nmesh.insert_attribute(Mesh::ATTRIBUTE_UV_0, vec![[u, v]; n]);\nmesh.compute_tangents().unwrap();","handlingStrategy":"validation","validationCode":"fn tangent_formats_ok(mesh: &Mesh) -> bool {\n    mesh.attribute(Mesh::ATTRIBUTE_POSITION).is_some_and(|v| v.as_float3().is_some())\n        && mesh.attribute(Mesh::ATTRIBUTE_NORMAL).is_some_and(|v| v.as_float3().is_some())\n        && mesh.attribute(Mesh::ATTRIBUTE_UV_0).is_some_and(|v| v.as_float2().is_some())\n}\n\nif tangent_formats_ok(&mesh) {\n    mesh.compute_tangents()?;\n}","typeGuard":null,"tryCatchPattern":"if let Err(GenerateTangentsError::InvalidVertexAttributeFormat(name, format)) =\n    mesh.compute_tangents()\n{\n    bevy::log::error!(\"'{name}' has format {format:?}; need Float32x3/Float32x3/Float32x2\");\n}","preventionTips":["POSITION/NORMAL must be Float32x3 and UV_0 Float32x2 before compute_tangents","Convert vec3 UVs to vec2 and unpack compressed normals at import time","Keep vertex compression as a post-tangent step in the pipeline"],"tags":["bevy","mesh","tangents","mikktspace","vertex-attribute","format-mismatch"],"backgroundTag":"vertex-attribute-format-mismatch","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"}