{"record":{"id":"1b6f22899b9c6b8a","repo":"bevyengine/bevy","slug":"unsupported-vertex-attribute-format","errorCode":null,"errorMessage":"Unsupported vertex attribute format","messagePattern":"Unsupported vertex attribute format","errorType":"exception","errorClass":"AccessFailed","httpStatus":null,"severity":"error","filePath":"crates/bevy_gltf/src/vertex_attributes.rs","lineNumber":38,"sourceCode":"        unnormalized_ctor: impl Fn(T) -> U,\n    ) -> U {\n        if self.0 {\n            normalized_ctor(value)\n        } else {\n            unnormalized_ctor(value)\n        }\n    }\n}\n\n/// An error that occurs when accessing buffer data\n#[derive(Error, Debug)]\npub enum AccessFailed {\n    /// Accessing the data failed because of an issue like a mismatch in stride,\n    /// or a buffer view slice failing.\n    #[error(\"Malformed vertex attribute data\")]\n    MalformedData,\n    /// The format supplied is unsupported for this operation.\n    #[error(\"Unsupported vertex attribute format\")]\n    UnsupportedFormat,\n}\n\n/// Helper for reading buffer data\nstruct BufferAccessor<'a> {\n    accessor: gltf::Accessor<'a>,\n    buffer_data: &'a Vec<Vec<u8>>,\n    normalization: Normalization,\n}\n\nimpl<'a> BufferAccessor<'a> {\n    /// Creates an iterator over the elements in this accessor\n    fn iter<T: gltf::accessor::Item>(self) -> Result<gltf::accessor::Iter<'a, T>, AccessFailed> {\n        gltf::accessor::Iter::new(self.accessor, |buffer: gltf::Buffer| {\n            self.buffer_data.get(buffer.index()).map(Vec::as_slice)\n        })\n        .ok_or(AccessFailed::MalformedData)\n    }","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_gltf/src/vertex_attributes.rs#L20-L56","documentation":"AccessFailed::UnsupportedFormat fires from two sites in vertex_attributes.rs: the catch-all of VertexAttributeIter::from_accessor (line 135) when the accessor's (DataType, Dimensions) pair is not in the supported table — FLOAT16 data, matrix types, or exotic combos like I8 Vec3 — and BufferAccessor::with_no_norm (line 64) when a float/uint accessor is marked \"normalized\": true, which only makes sense for signed/unsigned ints and is rejected. It reaches callers as ConvertAttributeError::AccessFailed(UnsupportedFormat, accessor_index).","triggerScenarios":"POSITION/TEXCOORD stored as VEC3/VEC2 of FLOAT16 (exporter 'half float' option); \"normalized\": true on a F32 accessor; MAT2/MAT3 attributes; I16 Vec3 colors.","commonSituations":"DCC precision settings ('Half Float'), KHR_mesh_quantization-style assets using unsupported component types/dimensions, custom attribute pipelines copying whatever the source mesh had.","solutions":["Re-export with float32 for standard attributes, or use one of the supported integer combos (U8/I8/U16/I16 in Vec2/Vec3/Vec4, U32/F32 in all dimensions).","Remove 'normalized' flags from float accessors.","If you need half-float or exotic layouts, convert to a supported layout in an offline step before loading."],"exampleFix":"// accessor (before)\n{ \"componentType\": 5123, \"type\": \"VEC3\", \"normalized\": true }  // U16 Vec3 unsupported combo\n// (after)\n{ \"componentType\": 5126, \"type\": \"VEC3\" }  // FLOAT Vec3, always supported","handlingStrategy":"validation","validationCode":"fn accessor_format_supported(a: &gltf::Accessor) -> bool {\n    use gltf::accessor::{DataType as D, Dimensions as V};\n    let float_like = matches!(a.data_type(), D::F32 | D::U32);\n    if a.normalized() && float_like { return false; } // with_no_norm rejects this\n    matches!((a.data_type(), a.dimensions()),\n        (D::F32, _) | (D::U32, _)\n        | (D::I16, V::Vec2) | (D::U16, V::Vec2) | (D::I16, V::Vec4) | (D::U16, V::Vec4)\n        | (D::I8, V::Vec2) | (D::U8, V::Vec2) | (D::I8, V::Vec4) | (D::U8, V::Vec4)\n        | (D::U16, V::Vec3) | (D::U8, V::Vec3))\n}","typeGuard":"fn is_supported_vertex_format(dt: gltf::accessor::DataType, dims: gltf::accessor::Dimensions) -> bool {\n    use gltf::accessor::{DataType as D, Dimensions as V};\n    matches!((dt, dims), (D::F32, _) | (D::U32, _) | (D::I16, V::Vec2) | (D::U16, V::Vec2)\n        | (D::I16, V::Vec4) | (D::U16, V::Vec4) | (D::I8, V::Vec2) | (D::U8, V::Vec2)\n        | (D::I8, V::Vec4) | (D::U8, V::Vec4) | (D::U16, V::Vec3) | (D::U8, V::Vec3))\n}","tryCatchPattern":"match err {\n    ConvertAttributeError::AccessFailed(AccessFailed::UnsupportedFormat, idx) => {\n        error!(\"accessor {idx} uses an unsupported componentType/type (or normalized floats); re-export with supported formats\");\n    }\n    other => return Err(other.into()),\n}","preventionTips":["Disable 'half float' precision in exporters for glTF output.","Quantize only to U8/U16/I8/I16 Vec2/Vec3/Vec4 combos the loader supports.","Never set normalized on float accessors."],"tags":["gltf","vertex-attributes","accessor","format","bevy"],"backgroundTag":"unsupported-vertex-format","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}