stride3d/stride · error · InvalidOperationException
Can'to detach camera
Error message
Can'to detach camera [{camera.Entity.Name}] from the graphics compositor. Another camera, {slot.Camera.Entity.Name}, is attached to this slot. What it means
DetachCameraFromSlot throws InvalidOperationException when the compositor slot matching the camera's slot id is occupied by a different camera, so the requested camera cannot be the one detached from that slot.
Solutions
- Ensure the Slot.Id being detached still points at the slot this camera actually occupies
- Detach before changing a camera's Slot.Id
- Reset camera.Slot.AttachedCompositor = null when it is known to be stale, then attach cleanly
- Keep one camera per slot and avoid mutating Slot.Id on attached cameras
Example fix
// before camera.Slot.Id = otherId; // slot bookkeeping now inconsistent Detach(camera); // after Detach(camera); // detach first camera.Slot.Id = otherId;
Defensive patterns
Strategy: validation
Validate before calling
var slot = camera.Slot.AttachedCompositor?.Cameras.FirstOrDefault(s => s.Id == camera.Slot.Id); if (slot == null || slot.Camera != camera) return; // wrong camera in slot
Try / catch
try { DetachCameraFromSlot(camera); }
catch (InvalidOperationException ex) when (ex.Message.Contains("Another camera")) { /* re-sync slot bookkeeping */ } Prevention
- Detach a camera before changing its Slot.Id
- Never swap Slot.Id values between attached cameras
- Keep one camera per slot and one slot per attached camera
- Reset stale AttachedCompositor references before re-attaching
When it happens
Trigger: The camera's Slot.Id equals an occupied slot, but slot.Camera points to another camera component — e.g. after swapping Slot.Id values between two cameras, or attaching camera B to a slot then trying to detach camera A whose slot id matches.
Common situations: Swapping or reusing camera slot IDs at runtime; copying slot settings between camera components; a new camera attached to the slot after the old one's attachment bookkeeping was lost.
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
- Unable to attach camera
- The camera [ ] is disabled and can't be attached
- The camera [ ] is already attached
- The camera [ ] isn't attached
- RenderView is null. Please make sure you have your camera…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b963faa069df5cf2.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Engine/Engine/Processors/CameraProcessor.cs:160
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)
{
for (var i = 0; i < graphicsCompositor.Cameras.Count; ++i)
{
var slot = graphicsCompositor.Cameras[i];
if (slot.Camera == camera)
{
slot.Camera = null;
}
}View on GitHub (pinned to 96fad776d2)