bevyengine/bevy · error · FromVertexAttributeError

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

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.

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)

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.