{"record":{"id":"77addc90fe981df7","repo":"bevyengine/bevy","slug":"the-component-is-immutable","errorCode":null,"errorMessage":"the `Component` is immutable","messagePattern":"the `Component` is immutable","errorType":"exception","errorClass":"GetEntityMutByIdError","httpStatus":null,"severity":"error","filePath":"crates/bevy_ecs/src/world/unsafe_world_cell.rs","lineNumber":1226,"sourceCode":"        // SAFETY: UnsafeEntityCell is only constructed for living entities and offers no despawn method\n        unsafe {\n            self.world()\n                .entities()\n                .entity_get_spawned_or_despawned_unchecked(self.entity)\n                .1\n        }\n    }\n}\n\n/// Error that may be returned when calling [`UnsafeEntityCell::get_mut_by_id`].\n#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]\npub enum GetEntityMutByIdError {\n    /// The [`ComponentInfo`](crate::component::ComponentInfo) could not be found.\n    #[error(\"the `ComponentInfo` could not be found\")]\n    InfoNotFound,\n    /// The [`Component`] is immutable. Creating a mutable reference violates its\n    /// invariants.\n    #[error(\"the `Component` is immutable\")]\n    ComponentIsImmutable,\n    /// This [`Entity`] does not have the desired [`Component`].\n    #[error(\"the `Component` could not be found\")]\n    ComponentNotFound,\n}\n\nimpl<'w> UnsafeWorldCell<'w> {\n    #[inline]\n    /// # Safety\n    /// - the returned `Table` is only used in ways that this [`UnsafeWorldCell`] has permission for.\n    /// - the returned `Table` is only used in ways that would not conflict with any existing borrows of world data.\n    unsafe fn fetch_table(self, location: EntityLocation) -> Option<&'w Table> {\n        // SAFETY:\n        // - caller ensures returned data is not misused and we have not created any borrows of component/resource data\n        // - `location` contains a valid `TableId`, so getting the table won't fail\n        unsafe { self.storages().tables.get(location.table_id) }\n    }\n","sourceCodeStart":1208,"sourceCodeEnd":1244,"githubUrl":"https://github.com/bevyengine/bevy/blob/396ca727080776bd313bb892423b7d94e03b81b4/crates/bevy_ecs/src/world/unsafe_world_cell.rs#L1208-L1244","documentation":"GetEntityMutByIdError::ComponentIsImmutable is returned by UnsafeEntityCell::get_mut_by_id when the target component was declared immutable via #[component(immutable)]. Immutable components forbid &mut access by design (their value is fixed after insertion), so requesting a mutable reference violates their invariants and the API refuses instead of handing out an aliasing pointer.","triggerScenarios":"Calling get_mut_by_id(component_id) for any component annotated #[component(immutable)]; generic/dynamic code that uniformly fetches components mutably by id without knowing which ones are immutable; tools (editors, dev-tools) that iterate all components of an entity and request &mut for each.","commonSituations":"Marking relationship hooks / fixed metadata components immutable and then hitting them from a generic mutator; refactoring a component to immutable without updating the code that mutates it; unsafe schedule code that assumes every component is mutable.","solutions":["Use shared access instead: get_by_id(component_id) returns the read-only pointer.","To 'change' an immutable component, despawn or use an entity-level API that replaces it (e.g. insert overwrites are still handled by the typed path — check the component's contract; mutation via &mut is not allowed).","In generic code, branch on world.components().get_info(id).map(|i| i.is_immutable()) before choosing get_mut_by_id vs get_by_id.","Reconsider whether the component really should be immutable if your design requires mutation."],"exampleFix":"// before\nlet c = cell.get_mut_by_id(id).unwrap(); // ComponentIsImmutable\n\n// after\nif cell.world().components().get_info(id).is_some_and(|i| i.is_immutable()) {\n    let c = cell.get_by_id(id); // shared access\n} else {\n    let c = cell.get_mut_by_id(id);\n}","handlingStrategy":"type-guard","validationCode":"let immutable = world\n    .components()\n    .get_info(component_id)\n    .is_some_and(|info| info.is_immutable());","typeGuard":"fn is_immutable(world: &World, id: ComponentId) -> bool {\n    world\n        .components()\n        .get_info(id)\n        .map(|info| info.is_immutable())\n        .unwrap_or(false)\n}","tryCatchPattern":"match cell.get_mut_by_id(component_id) {\n    Err(GetEntityMutByIdError::ComponentIsImmutable) => {\n        let shared = cell.get_by_id(component_id); // fall back to read-only access\n    }\n    other => { /* ... */ }\n}","preventionTips":["In generic per-component tooling, branch on ComponentInfo::is_immutable before choosing get_mut_by_id.","Read the component's declaration: #[component(immutable)] forbids &mut by contract.","Prefer shared access for inspection tools (editors, dev-tools)."],"tags":["bevy","ecs","immutable-component","unsafe-world-cell","component"],"backgroundTag":"immutable-component-mutation","analyzedSha":"396ca727080776bd313bb892423b7d94e03b81b4","analyzedAt":"2026-08-20T16:12:39.808Z","contentChangedAt":"2026-08-20T16:12:39.808Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}