bevyengine/bevy · error
underlying type does not reflect `PartialEq` and hence doesn
Error message
underlying type does not reflect `PartialEq` and hence doesn't support equality checks
What it means
DynamicMap stores erased Box<dyn PartialReflect> keys in a hash table and looks them up by hashing and equality. internal_eq calls key.reflect_partial_eq(&**other) and expects the result: for types that do not reflect PartialEq, reflect_partial_eq returns None, and this expect panics with 'underlying type does not reflect `PartialEq`...'. Note DynamicMap::get/get_mut hash the key too, so key types also need reflected Hash.
Source
Thrown at crates/bevy_reflect/src/map.rs:263
self.represented_type = represented_type;
}
/// Inserts a typed key-value pair into the map.
pub fn insert<K: PartialReflect, V: PartialReflect>(&mut self, key: K, value: V) {
self.insert_boxed(Box::new(key), Box::new(value));
}
fn internal_hash(value: &dyn PartialReflect) -> u64 {
value.reflect_hash().expect(&hash_error!(value))
}
fn internal_eq(
key: &dyn PartialReflect,
) -> impl FnMut(&(Box<dyn PartialReflect>, Box<dyn PartialReflect>)) -> bool + '_ {
|(other, _)| {
key
.reflect_partial_eq(&**other)
.expect("underlying type does not reflect `PartialEq` and hence doesn't support equality checks")
}
}
}
impl Map for DynamicMap {
fn get(&self, key: &dyn PartialReflect) -> Option<&dyn PartialReflect> {
self.hash_table
.find(Self::internal_hash(key), Self::internal_eq(key))
.map(|(_, value)| &**value)
}
fn get_mut(&mut self, key: &dyn PartialReflect) -> Option<&mut dyn PartialReflect> {
self.hash_table
.find_mut(Self::internal_hash(key), Self::internal_eq(key))
.map(|(_, value)| &mut **value)
}
fn len(&self) -> usize {View on GitHub (pinned to 396ca72708)
Solutions
- Add the missing reflect data to the key type: #[reflect(PartialEq, Hash)] (and derive/implement PartialEq + Hash) so reflect_partial_eq returns Some.
- Use simple key types that already reflect PartialEq/Hash (String, integers, Entity) for dynamic map keys.
- Check support before lookup: key.reflect_partial_eq(key.as_partial_reflect()).is_some() (and reflect_hash().is_some()) and fall back to iteration or rejection.
- If the key is dynamic, set represented type info via set_represented_type so it converts to a PartialEq-supporting type before use.
Example fix
// before #[derive(Reflect, TypePath)] #[reflect_value] // no PartialEq/Hash -> DynamicMap lookups panic struct Key(u64); // after #[derive(Reflect, TypePath, PartialEq, Eq, Hash)] #[reflect_value(PartialEq, Hash)] struct Key(u64);
Defensive patterns
Strategy: validation
Validate before calling
fn key_supports_eq_and_hash(key: &dyn PartialReflect) -> bool {
key.reflect_hash().is_some() && key.reflect_partial_eq(key.as_partial_reflect()).is_some()
}
if key_supports_eq_and_hash(probe.as_ref()) {
let hit = dynamic_map.get(probe.as_ref());
} else {
// iterate entries or reject the key type
} Type guard
fn safe_dynamic_key<K: PartialReflect + ?Sized>(k: &K) -> Option<&K> {
(k.reflect_partial_eq(k.as_partial_reflect()).is_some()).then_some(k)
} Prevention
- Register #[reflect(PartialEq, Hash)] (plus the traits) on every type used as a dynamic map key.
- Prefer String/integer/Entity keys for DynamicMap-driven lookups.
- Unit-test key lookups for each custom key type you register.
When it happens
Trigger: Calling DynamicMap::get/get_mut (or operations that look keys up) with a key whose type does not implement reflected PartialEq — e.g. a custom #[reflect_value] opaque type without #[reflect(PartialEq, Hash)], or a dynamic key that represents such a type.
Common situations: Custom opaque key types registered without PartialEq/Hash reflect data; building DynamicMap from user data with exotic keys; mirrors of typed maps where the key type changed into one lacking PartialEq.
Related errors
- Attempted to insert invalid value of type {}.
- Attempted to push invalid value of type {}.
- Attempted to insert invalid value of type {}.
- Attempted to push invalid value of type {}.
- Failed to insert attribute. Invalid attribute format for {}.
AI-assisted analysis of bevyengine/bevy@396ca72708 (2026-08-20).
Data as JSON: /api/errors/0b3735091f515956.
Report an issue: GitHub.