{"record":{"id":"4ed5ac30ef7541fc","repo":"bevyengine/bevy","slug":"vertex-attribute-0-has-format-1-but-expected","errorCode":null,"errorMessage":"Vertex attribute {0} has format {1:?} but expected {3:?} for target attribute {2}","messagePattern":"Vertex attribute (.+?) has format (.+?) but expected (.+?) for target attribute (.+?)","errorType":"exception","errorClass":"ConvertAttributeError","httpStatus":null,"severity":"error","filePath":"crates/bevy_gltf/src/vertex_attributes.rs","lineNumber":267,"sourceCode":"            s => s.into_any_values(false),\n        }\n    }\n}\n\nenum ConversionMode {\n    Any,\n    Rgba,\n    JointIndex,\n    JointWeight,\n    TexCoord,\n}\n\n/// Errors that can occur during the `convert_attribute` function.\n#[derive(Error, Debug)]\npub enum ConvertAttributeError {\n    /// The loaded format ws different than the attribute's intended format.\n    /// Such as if a `Float32x3` was loaded as a `Float32x2`.\n    #[error(\"Vertex attribute {0} has format {1:?} but expected {3:?} for target attribute {2}\")]\n    WrongFormat(String, VertexFormat, String, VertexFormat),\n    /// Fetching values from the glTF Accessor failed\n    #[error(\"{0} in accessor {1}\")]\n    AccessFailed(AccessFailed, usize),\n    /// A vertex attribute name was not one of the gltf crate's well-known attributes,\n    /// nor was it registered by a user as a custom attribute. Therefore it is unknown.\n    #[error(\"Unknown vertex attribute {0}\")]\n    UnknownName(String),\n}\n\n/// map glTF vertex attributes into their `MeshVertexAttribute` forms, optionally\n/// converting values if necessary.\npub fn convert_attribute(\n    semantic: gltf::Semantic,\n    accessor: gltf::Accessor,\n    buffer_data: &Vec<Vec<u8>>,\n    custom_vertex_attributes: &HashMap<Box<str>, MeshVertexAttribute>,\n    convert_coordinates: bool,","sourceCodeStart":249,"sourceCodeEnd":285,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_gltf/src/vertex_attributes.rs#L249-L285","documentation":"ConvertAttributeError::WrongFormat(String semantic, VertexFormat loaded, String attr, VertexFormat expected) is thrown at vertex_attributes.rs:333-345 after conversion: the materialized values' VertexFormat must exactly equal the fixed format of the target MeshVertexAttribute (POSITION must be Float32x3, UV_0 Float32x2, JOINT_INDEX Uint16x4, ...). The classic trigger is an accessor whose format has no conversion path for its semantic — e.g. TEXCOORD_0 as UNnormalized U8x2: into_tex_coord_values (line 241-251) only converts normalized U8x2/U16x2, so values stay Uint8x2 while ATTRIBUTE_UV_0 requires Float32x2.","triggerScenarios":"TEXCOORD_0 with \"normalized\": false byte/short data; JOINTS_0 as normalized U16x4 (loads Unorm16x4, expected Uint16x4); custom vertex attributes registered with a MeshVertexAttribute format that does not match the stored data; POSITION exported as VEC2.","commonSituations":"Quantized/optimized glTFs (KHR_mesh_quantization derivatives) using unnormalized bytes; teams registering custom attributes with a guessed format; exporters writing unusual joint encodings.","solutions":["Re-export attributes in the formats Bevy converts for that semantic (float32 positions/uvs; normalized U8/U16 texcoords; unnormalized U8/U16 joints; normalized weights).","For _CUSTOM_ attributes, register the MeshVertexAttribute with a format matching the accessor data (or convert the data to match the registered format).","Check the error fields: arg 1 is the semantic, arg 2 what was loaded, arg 4 what was expected — adjust whichever side is wrong."],"exampleFix":"// TEXCOORD_0 accessor (before)\n{ \"componentType\": 5121, \"type\": \"VEC2\", \"normalized\": false }\n// (after) normalized bytes convert to Float32x2 as expected\n{ \"componentType\": 5121, \"type\": \"VEC2\", \"normalized\": true }","handlingStrategy":"validation","validationCode":"use bevy_mesh::VertexFormat;\nfn semantic_format_ok(semantic: &gltf::Semantic, loaded: VertexFormat) -> bool {\n    let expected = match semantic {\n        gltf::Semantic::Positions => VertexFormat::Float32x3,\n        gltf::Semantic::Normals => VertexFormat::Float32x3,\n        gltf::Semantic::Tangents => VertexFormat::Float32x4,\n        gltf::Semantic::TexCoords(0..=1) => VertexFormat::Float32x2,\n        gltf::Semantic::Colors(0) => VertexFormat::Float32x4,\n        gltf::Semantic::Joints(0) => VertexFormat::Uint16x4,\n        gltf::Semantic::Weights(0) => VertexFormat::Float32x4,\n        _ => return true,\n    };\n    loaded == expected\n}","typeGuard":"fn is_wrong_format(err: &ConvertAttributeError) -> Option<(&str, &VertexFormat, &VertexFormat)> {\n    match err {\n        ConvertAttributeError::WrongFormat(sem, loaded, _, expected) => Some((sem, loaded, expected)),\n        _ => None,\n    }\n}","tryCatchPattern":"match err {\n    ConvertAttributeError::WrongFormat(sem, loaded, name, expected) => {\n        error!(\"{sem} stored as {loaded:?} but {name} needs {expected:?}; re-export the attribute in a convertible format\");\n    }\n    other => return Err(other.into()),\n}","preventionTips":["Export standard attributes with plain float32 (and normalized int texcoords/joints/weights).","Register custom _ATTRIBUTES with a MeshVertexAttribute format matching the data.","Automated import check: assert semantic->expected-format mapping before loading."],"tags":["gltf","vertex-attributes","vertex-format","texcoord","bevy"],"backgroundTag":"vertex-format-mismatch","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}