stride3d/stride · error · InvalidOperationException
The camera [ ] is already attached
Error message
The camera [{camera.Entity.Name}] is already attached What it means
CameraProcessor.AttachCameraToSlot throws InvalidOperationException when the CameraComponent's Slot already has an AttachedCompositor, i.e. the camera is already bound to some compositor slot. A camera cannot be attached to more than one slot at a time.
Solutions
- Check camera.Slot.AttachedCompositor == null before attaching, or skip if already attached
- Set camera.Slot.AttachedCompositor = null (detach) before re-attaching elsewhere
- Use a separate CameraComponent per slot instead of reusing one instance
- Ensure attach logic runs only once (guard with a bool or only on entity add)
Example fix
// before
cameraProcessor.AttachCameraToSlot(compositor, camera);
// after
if (camera.Slot.AttachedCompositor == null)
cameraProcessor.AttachCameraToSlot(compositor, camera); Defensive patterns
Strategy: type-guard
Validate before calling
if (camera.Slot?.AttachedCompositor != null) return; // already attached
Type guard
bool AlreadyAttached(CameraComponent c) => c?.Slot?.AttachedCompositor != null;
Try / catch
try { AttachCameraToSlot(compositor, camera); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already attached")) { /* no-op */ } Prevention
- Run attach logic only once per camera (entity-add time, not every frame)
- Use one CameraComponent per slot
- Detach before re-attaching elsewhere
- Never share camera components across scene setups
When it happens
Trigger: Attaching the same CameraComponent twice (e.g. adding the entity again, re-running setup logic each frame, or reusing one camera component across two GraphicsCompositor slots).
Common situations: Re-adding a camera entity to a scene without removing it first; sharing a single camera component between two scene setups; script that calls attach logic every Update instead of once.
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 [ ] isn't 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/1b4cad2a850f03af.
Report an issue: GitHub.
Appendix: source
Thrown at sources/engine/Stride.Engine/Engine/Processors/CameraProcessor.cs:132
}
}
}
protected override void OnEntityComponentRemoved(Entity entity, CameraComponent component, CameraComponent data)
{
if (component.Slot.AttachedCompositor != null)
DetachCameraFromSlot(component);
}
private void OnCameraSlotsChanged(object sender, ref FastTrackingCollectionChangedEventArgs e)
{
cameraSlotsDirty = true;
}
private void AttachCameraToSlot(GraphicsCompositor graphicsCompositor, CameraComponent camera)
{
if (!camera.Enabled) throw new InvalidOperationException($"The camera [{camera.Entity.Name}] is disabled and can't be attached");
if (camera.Slot.AttachedCompositor != null) throw new InvalidOperationException($"The camera [{camera.Entity.Name}] is already attached");
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)
{View on GitHub (pinned to 96fad776d2)