stride3d/stride · error · InvalidOperationException

This component is already attached to entity

Error message

This component is already attached to entity [{item.Entity}] and cannot be attached to [{entity}]

What it means

A component instance can belong to only one Entity at a time. ValidateItem throws InvalidOperationException when the component being added already has item.Entity set to a different entity and the collection does not allow replacing a foreign-entity attachment (AllowReplaceForeignEntity).

Solutions

  1. Remove the component from its current entity (oldEntity.Components.Remove(component)) before adding it to the new entity
  2. Create a new component instance per entity instead of sharing
  3. Clone the component's state onto a fresh instance for the target entity

Example fix

// before
newEntity.Components.Add(sharedComponent);
// after
oldEntity.Components.Remove(sharedComponent);
newEntity.Components.Add(sharedComponent);
Defensive patterns

Strategy: validation

Validate before calling

if (component.Entity != null && component.Entity != targetEntity)
    component.Entity.Components.Remove(component);
targetEntity.Components.Add(component);

Type guard

static bool IsUnattached(Stride.Engine.EntityComponent c) => c?.Entity == null;

Try / catch

try { targetEntity.Components.Add(component); }
catch (InvalidOperationException ex) when (ex.Message.StartsWith("This component is already attached")) { /* detach from old entity first */ }

Prevention

When it happens

Trigger: Adding a component that is currently attached to entity A into entity B's Components collection without detaching it first; sharing one component instance between two entities.

Common situations: Pooling and reassigning components between entities without resetting Entity; accidental reuse of a shared singleton component across scene entities; move-entity refactors that copy component references.

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


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/4473e1ef8be0f4c5. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Engine/Engine/EntityComponentCollection.cs:240

                    previousItem = existingItem;
                }
                else
                {
                    if (ReferenceEquals(existingItem, item))
                    {
                        throw new InvalidOperationException($"Cannot add a same component multiple times. Already set at index [{i}]");
                    }

                    if (onlySingleComponent && componentType == existingItem.GetType())
                    {
                        throw new InvalidOperationException($"Cannot add a component of type [{componentType}] multiple times");
                    }
                }
            }

            if (!AllowReplaceForeignEntity && entity != null && item.Entity != null)
            {
                throw new InvalidOperationException($"This component is already attached to entity [{item.Entity}] and cannot be attached to [{entity}]");
            }

            if (entity != null)
            {
                var transform = item as TransformComponent;
                if (transform != null)
                {
                    entity.TransformValue = transform;
                }
                else if (previousItem is TransformComponent)
                {
                    // If previous item was a transform component but we are actually replacing it, we should 
                    entity.TransformValue = null;
                }

                item.Entity = entity;
            }

View on GitHub (pinned to 96fad776d2)