stride3d/stride · error · InvalidOperationException
The camera [ ] isn't attached
Error message
The camera [{camera.Entity.Name}] isn't attached What it means
DetachCameraFromSlot throws InvalidOperationException when the given CameraComponent's Slot has no AttachedCompositor, meaning the camera is not currently attached anywhere and thus cannot be detached.
Solutions
- Check camera.Slot?.AttachedCompositor != null before detaching
- Ensure the detach path is idempotent: skip instead of throwing when not attached
- Don't change camera.Slot while it is attached; detach first, then reassign
- If removing an entity, verify the camera went through the attach path in this processor
Example fix
// before
cameraProcessor.DetachCameraFromSlot(camera);
// after
if (camera.Slot.AttachedCompositor != null)
cameraProcessor.DetachCameraFromSlot(camera); Defensive patterns
Strategy: type-guard
Validate before calling
if (camera.Slot?.AttachedCompositor == null) return; // nothing to detach
Type guard
bool CanDetach(CameraComponent c) => c?.Slot?.AttachedCompositor != null;
Try / catch
try { DetachCameraFromSlot(camera); }
catch (InvalidOperationException ex) when (ex.Message.Contains("isn't attached")) { /* already detached; ignore */ } Prevention
- Make detach paths idempotent (check before detaching)
- Don't change camera.Slot while attached; detach first
- Track attachment state in your own code to avoid double-detach
- Only remove camera entities that went through attach
When it happens
Trigger: Calling detach logic (via the Draw pass or OnEntityComponentRemoved) on a camera whose Slot.AttachedCompositor is null: it was never attached, was already detached, or its Slot was changed while attached.
Common situations: Removing a camera entity from a scene that was never attached; double-detach; reassigning camera.Slot (nulls/replaces attachment state) then removing the entity; disabling cameras and assuming detach is always safe.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- The camera [ ] is disabled and can't be attached
- The camera [ ] is already attached
- Custom strides is not supported with packed PixelFormats
- Unable to attach camera
- Can'to detach camera
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/13c3015538b05f04.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Engine/Engine/Processors/CameraProcessor.cs:152
for (var i = 0; i < graphicsCompositor.Cameras.Count; ++i)
{
var slot = graphicsCompositor.Cameras[i];
if (slot.Id == camera.Slot.Id)
{
if (slot.Camera != null)
throw new InvalidOperationException($"Unable to attach camera [{camera.Entity.Name}] to the graphics compositor. Another camera, [{slot.Camera.Entity.Name}], is enabled and already attached to this slot.");
slot.Camera = camera;
camera.Slot.AttachedCompositor = graphicsCompositor;
break;
}
}
}
private static void DetachCameraFromSlot(CameraComponent camera)
{
if (camera.Slot.AttachedCompositor == null)
throw new InvalidOperationException($"The camera [{camera.Entity.Name}] isn't attached");
for (var i = 0; i < camera.Slot.AttachedCompositor.Cameras.Count; ++i)
{
var slot = camera.Slot.AttachedCompositor.Cameras[i];
if (slot.Id == camera.Slot.Id)
{
if (slot.Camera != camera)
throw new InvalidOperationException($"Can'to detach camera [{camera.Entity.Name}] from the graphics compositor. Another camera, {slot.Camera.Entity.Name}, is attached to this slot.");
slot.Camera = null;
break;
}
}
camera.Slot.AttachedCompositor = null;
}
private static void DetachCameraFromAllSlots(CameraComponent camera, GraphicsCompositor graphicsCompositor)
{View on GitHub (pinned to 96fad776d2)