{"record":{"id":"990e73587bf225c9","repo":"bevyengine/bevy","slug":"cannot-call-reflectcomponent-reflect-unchecked-m","errorCode":null,"errorMessage":"Cannot call `ReflectComponent::reflect_unchecked_mut` on component {name}. It is immutable, and cannot modified through reflection","messagePattern":"Cannot call `ReflectComponent::reflect_unchecked_mut` on component (.+?)\\. It is immutable, and cannot modified through reflection","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/reflect/component.rs","lineNumber":393,"sourceCode":"            reflect_mut: |entity| {\n                if !C::Mutability::MUTABLE {\n                    let name = DebugName::type_name::<C>();\n                    let name = name.shortname();\n                    panic!(\"Cannot call `ReflectComponent::reflect_mut` on component {name}. It is immutable, and cannot modified through reflection\");\n                }\n\n                // SAFETY: guard ensures `C` is a mutable component\n                unsafe {\n                    entity\n                        .into_mut_assume_mutable::<C>()\n                        .map(|c| c.map_unchanged(|value| value as &mut dyn Reflect))\n                }\n            },\n            reflect_unchecked_mut: |entity| {\n                if !C::Mutability::MUTABLE {\n                    let name = DebugName::type_name::<C>();\n                    let name = name.shortname();\n                    panic!(\"Cannot call `ReflectComponent::reflect_unchecked_mut` on component {name}. It is immutable, and cannot modified through reflection\");\n                }\n\n                // SAFETY: reflect_unchecked_mut is an unsafe function pointer used by\n                // `reflect_unchecked_mut` which must be called with an UnsafeEntityCell with access to the component `C` on the `entity`\n                // guard ensures `C` is a mutable component\n                let c = unsafe { entity.get_mut_assume_mutable::<C>() };\n                c.map(|c| c.map_unchanged(|value| value as &mut dyn Reflect))\n            },\n            register_component: |world: &mut World| -> ComponentId {\n                world.register_component::<C>()\n            },\n            map_entities: |reflect: &mut dyn Reflect, mut mapper: &mut dyn EntityMapper| {\n                let component = reflect.downcast_mut::<C>().unwrap();\n                Component::map_entities(component, &mut mapper);\n            },\n        })\n    }\n}","sourceCodeStart":375,"sourceCodeEnd":411,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/reflect/component.rs#L375-L411","documentation":"`reflect_unchecked_mut` is the unsafe variant of `ReflectComponent`'s mutable access: it skips aliasing checks and directly returns a `&mut dyn Reflect` for the component. Like `reflect_mut`, it is guarded by the component's declared mutability — for a component with `type Mutability = Immutable`, the guard panics rather than let reflection break the immutability contract, even though the caller already opted into `unsafe`.","triggerScenarios":"Calling `ReflectComponent::reflect_unchecked_mut` (or an `UnsafeEntityCell`-based reflective mutation path) on a component whose `Component::Mutability` is `Immutable` — typically deep editor, scene-spawn, or framework code that uses the unchecked API for performance on all components.","commonSituations":"Porting internal tooling from Bevy versions before mutable/immutable components existed (all components were mutable); inspector or replay tools that iterate every registered `ReflectComponent` and call the unchecked mutator; user hierarchies built on `ChildOf` (immutable) being edited reflectively.","solutions":["Switch to the immutable workflow: `reflect()` to read, construct the replacement value, `insert()` to write","If the component genuinely needs reflective mutation, declare `type Mutability = Mutable` in its `Component` impl","Guard tooling loops so immutable components are filtered out before the unsafe call"],"exampleFix":"// before\nlet c = unsafe { reflect_component.reflect_unchecked_mut(entity_cell) }; // panics for Immutable\n\n// after — make the component mutable, or replace instead of mutating\nimpl Component for Marker { type Mutability = Mutable; }","handlingStrategy":"validation","validationCode":"// Before the unchecked path, verify the component's mutability\nif <C as Component>::Mutability::MUTABLE {\n    let c = unsafe { reflect_component.reflect_unchecked_mut(entity_cell) };\n} else {\n    // read-only path: reflect() then insert() a replacement\n}","typeGuard":"fn is_reflect_mutable<C: Component>() -> bool { C::Mutability::MUTABLE }","tryCatchPattern":null,"preventionTips":["Audit every unsafe reflect_unchecked_mut call site for the mutability precondition — the unsafe contract does not cover it","Keep a static list of immutable components when writing generic tooling","Run editor flows against a fixture entity set that includes known-immutable components (e.g. ChildOf) in CI"],"tags":["bevy","ecs","reflection","immutability","unsafe","panic"],"backgroundTag":"immutable-component-mutation","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}