bevyengine/bevy · error · ReflectKindMismatchError

kind mismatch: expected {expected:?}, received {received:?}

Error message

kind mismatch: expected {expected:?}, received {received:?}

What it means

ReflectKindMismatchError is returned by the cast helpers generated with impl_cast_method! on the ReflectRef/ReflectMut/ReflectOwned enums (obtained via PartialReflect::reflect_ref/reflect_mut/reflect_owned), e.g. casting to the Map/List/Struct variant. If the value's actual kind differs, the error reports expected vs received ReflectKind. It also converts into ApplyError::MismatchedKinds inside try_apply.

Source

Thrown at crates/bevy_reflect/src/kind.rs:138

                    $name::List(_) => Self::List,
                    $name::Array(_) => Self::Array,
                    $name::Map(_) => Self::Map,
                    $name::Set(_) => Self::Set,
                    $name::Enum(_) => Self::Enum,
                    #[cfg(feature = "functions")]
                    $name::Function(_) => Self::Function,
                    $name::Opaque(_) => Self::Opaque,
                }
            }
        }
    };
}

/// Caused when a type was expected to be of a certain [kind], but was not.
///
/// [kind]: ReflectKind
#[derive(Debug, Error)]
#[error("kind mismatch: expected {expected:?}, received {received:?}")]
pub struct ReflectKindMismatchError {
    /// Expected kind.
    pub expected: ReflectKind,
    /// Received kind.
    pub received: ReflectKind,
}

macro_rules! impl_cast_method {
    ($name:ident : Opaque => $retval:ty) => {
        #[doc = "Attempts a cast to a [`PartialReflect`] trait object."]
        #[doc = "\n\nReturns an error if `self` is not the [`Self::Opaque`] variant."]
        pub fn $name(self) -> Result<$retval, ReflectKindMismatchError> {
            match self {
                Self::Opaque(value) => Ok(value),
                _ => Err(ReflectKindMismatchError {
                    expected: ReflectKind::Opaque,
                    received: self.kind(),
                }),

View on GitHub (pinned to 396ca72708)

Solutions

  1. Branch on value.reflect_kind() (or match ReflectRef) before casting, and cover all kinds.
  2. Use try_apply/try_as_* Result-returning APIs and handle Err instead of unwrap.
  3. Validate external data kind early (e.g. require ReflectKind::Map before map processing) and reject with a clear message.
  4. If the kinds should match, fix the data source or the generic bounds so the right kind reaches the cast.

Example fix

// before
let r = value.reflect_ref().into_map().unwrap(); // panics on Err(ReflectKindMismatchError)

// after
match value.reflect_ref() {
    ReflectRef::Map(m) => { /* map logic */ }
    other => warn!("expected map, got {:?}", ReflectKind::from(other)),
}
Defensive patterns

Strategy: try-catch

Validate before calling

if value.reflect_kind() != ReflectKind::Map {
    return; // skip early instead of hitting the cast error
}

Type guard

fn is_reflected_map(value: &dyn PartialReflect) -> bool {
    value.reflect_kind() == ReflectKind::Map
}

Try / catch

use bevy_reflect::ReflectKindMismatchError;

match value.reflect_ref().into_map() {
    Ok(map) => { /* map logic */ }
    Err(ReflectKindMismatchError { expected, received }) => {
        warn!("kind mismatch: expected {expected:?}, received {received:?}");
    }
}

Prevention

When it happens

Trigger: Calling a kind-cast on reflect_ref()/reflect_mut()/reflect_owned() for the wrong variant, e.g. value.reflect_ref().into_map() on a Vec, or try_as_struct-style helpers on an opaque value; also surfaced as 'attempted to apply X to Y' when try_apply hits a kind mismatch.

Common situations: Generic reflection tools (inspectors, serializers, diff/patch code) that assume input kinds; processing deserialized dynamic data whose kind differs from the destination; handling values from untrusted/external sources through PartialReflect.

Related errors


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