bevyengine/bevy · error · FromVertexAttributeError

cannot convert VertexAttributeValues

Error message

cannot convert VertexAttributeValues::{variant} to {into}

What it means

bevy_mesh implements TryFrom<VertexAttributeValues> for concrete Vec<T> types in crates/bevy_mesh/src/conversions.rs. Conversion succeeds only when the enum variant exactly matches the target component type (Float32x3 -> Vec<Vec3>, Uint32x3 -> Vec<UVec3>, and so on). Any other pairing returns FromVertexAttributeError, whose message names the stored variant and the requested target type.

Solutions

  1. Match on the VertexAttributeValues variant and read the concrete Vec inside it
  2. Request the target type that matches VertexFormat::from(&values)
  3. Use variant helpers such as VertexAttributeValues::as_float3() (crates/bevy_mesh/src/vertex.rs:460) for position data

Example fix

// before
let positions: Vec<Vec3> = values.try_into().unwrap(); // Err when variant != Float32x3

// after
let positions: Option<&[[f32; 3]]> = values.as_float3();
match positions {
    Some(data) => use_positions(data),
    None => warn!(?values, "positions are not Float32x3"),
}
Defensive patterns

Strategy: try-catch

Validate before calling

use bevy_mesh::VertexAttributeValues;

// check the exact pairing before converting
fn convertible_to_vec3(values: &VertexAttributeValues) -> bool {
    matches!(values, VertexAttributeValues::Float32x3(_))
}

Type guard

fn as_float3_slice(values: &VertexAttributeValues) -> Option<&[[f32; 3]]> {
    values.as_float3() // Some only for the Float32x3 variant
}

Try / catch

// inspect the variant instead of guessing a target type
match values {
    VertexAttributeValues::Float32x3(data) => { /* data: &Vec<[f32; 3]> */ }
    VertexAttributeValues::Uint32x3(data) => { /* data: &Vec<[u32; 3]> */ }
    other => warn!(?other, "unsupported attribute variant"),
}

Prevention

When it happens

Trigger: let positions: Vec<u32> = values.try_into()?; on VertexAttributeValues::Float32x3; requesting Vec<Vec2> from a Float32x3 attribute; requesting Vec<Vec4> from Unorm8x4 color data; reading Uint16-based data as Vec<u32>.

Common situations: Generic mesh-processing code that assumes one component type for all meshes; handling compressed (half-float/unorm) attributes as f32 vectors; mixing u16/u32 conventions when reading attributes from imported assets.

Related errors


AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20). Data as JSON: /api/errors/47221247d2d76a57. Report an issue: GitHub.

Appendix: source

Thrown at crates/bevy_mesh/src/conversions.rs:32

//!
//! // converting bevy_mesh::VertexAttributeValues to std::vec::Vec with two ways
//! let result_into: Vec<[u32; 4]> = values.clone().try_into().unwrap();
//! let result_from: Vec<[u32; 4]> = Vec::try_from(values.clone()).unwrap();
//!
//! // getting an error when trying to convert incorrectly
//! let error: Result<Vec<u32>, _> = values.try_into();
//!
//! assert_eq!(buffer, result_into);
//! assert_eq!(buffer, result_from);
//! assert!(error.is_err());
//! ```

use super::VertexAttributeValues;
use bevy_math::{IVec2, IVec3, IVec4, UVec2, UVec3, UVec4, Vec2, Vec3, Vec3A, Vec4};
use thiserror::Error;

#[derive(Debug, Clone, Error)]
#[error("cannot convert VertexAttributeValues::{variant} to {into}")]
pub struct FromVertexAttributeError {
    from: VertexAttributeValues,
    variant: &'static str,
    into: &'static str,
}

impl FromVertexAttributeError {
    fn new<T: 'static>(from: VertexAttributeValues) -> Self {
        Self {
            variant: from.enum_variant_name(),
            into: core::any::type_name::<T>(),
            from,
        }
    }
}

macro_rules! impl_from {
    ($from:ty, $variant:tt) => {

View on GitHub (pinned to 396ca72708)