stride3d/stride · error · InvalidOperationException

Model already have a parent.

Error message

Model already have a parent.

What it means

When a Model is added to another Model's Children collection, Model.Children_CollectionChanged assigns itself as the child's parent. If the child already has a different parent, the engine throws InvalidOperationException, because a Model may only belong to one parent at a time.

Solutions

  1. Remove the child from its current parent's Children collection before adding it to a new one
  2. Create a new Model instance (or clone) instead of sharing one instance between parents
  3. Verify no code path adds the same child twice to the same or another parent

Example fix

// before
parent1.Children.Add(sharedChild);
parent2.Children.Add(sharedChild); // throws
// after
parent1.Children.Remove(sharedChild);
parent2.Children.Add(sharedChild);
Defensive patterns

Strategy: validation

Validate before calling

if (child.parent != null)
    throw new InvalidOperationException("Child model already has a parent; remove it first.");
newParent.Children.Add(child);

Type guard

static bool CanAttach(Model child) => child.parent == null;

Try / catch

try { newParent.Children.Add(child); }
catch (InvalidOperationException ex) when (ex.Message == "Model already have a parent.") {
    child.parent?.Children.Remove(child);
    newParent.Children.Add(child);
}

Prevention

When it happens

Trigger: Adding the same Model instance to the Children collection of two different parent Models, or to the same parent twice after it already has a parent set.

Common situations: Building scene hierarchies by reusing shared model instances across entities/parents; cloning code that copies children without detaching them from the old parent first.

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/88526f3ac0247acf. Report an issue: GitHub.

Appendix: source

Thrown at sources/engine/Stride.Rendering/Rendering/Model.cs:156

            {
                var meshCopy = new Mesh(mesh);
                result.Meshes.Add(meshCopy);
            }

            result.Skeleton = Skeleton;
            result.BoundingBox = BoundingBox;

            return result;
        }

        private void Children_CollectionChanged(object sender, TrackingCollectionChangedEventArgs e)
        {
            var child = (Model)e.Item;
            switch (e.Action)
            {
                case NotifyCollectionChangedAction.Add:
                    if (child.parent != null)
                        throw new InvalidOperationException("Model already have a parent.");
                    child.parent = this;
                    break;
                case NotifyCollectionChangedAction.Remove:
                    if (child.parent != this)
                        throw new InvalidOperationException("Model doesn't have expected parent.");
                    child.parent = null;
                    break;
            }
        }
    }
}

View on GitHub (pinned to 96fad776d2)