stride3d/stride · error · InvalidOperationException

This scene already has a Parent. Detach it first.

Error message

This scene already has a Parent. Detach it first.

What it means

Thrown by Scene.SceneCollection.InsertItem when a child scene being inserted still has a Parent. A scene in Stride may only belong to one parent at a time; inserting an already-parented scene would silently create a second ownership link and corrupt scene-tree bookkeeping (Children/Parent consistency and tracking), so the collection requires the scene to be detached from its current parent first.

Solutions

  1. Remove the child scene from its current parent's Children before re-parenting
  2. Check scene.Parent == null before adding; clone the scene asset if it must exist in two places
  3. Load a separate instance of the scene asset for each parent (do not share Scene objects)
  4. Ensure scene parenting is changed through the Children collection, not internal fields

Example fix

// before
parentA.Children.Add(sharedChild);
parentB.Children.Add(sharedChild); // throws
// after
parentB.Children.Remove is not needed — instead:
var childCopy = new Scene(); /* load separate instance */;
parentB.Children.Add(childCopy);
Defensive patterns

Strategy: validation

Validate before calling

if (childScene.Parent != null) childScene.Parent.Children.Remove(childScene);
parentScene.Children.Add(childScene);

Type guard

bool CanParent(Scene child) => child.Parent == null;

Try / catch

try { parent.Children.Add(childScene); }
catch (InvalidOperationException ex) when (ex.Message.Contains("already has a Parent")) { /* detach from old parent first */ }

Prevention

When it happens

Trigger: Adding to scene.Children a Scene instance whose Parent property is non-null — e.g. it is already a child of another scene; re-adding the same child scene; sharing a scene instance between two scene trees.

Common situations: Loading prefabs/sub-scenes that reference the same child Scene instance from multiple places; switching a sub-scene to a different parent without removing it first; accidentally instantiating one Scene asset as a shared object.

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

Appendix: source

Thrown at sources/engine/Stride.Engine/Engine/Scene.cs:159

                base.RemoveItem(index);
            }
        }

        [DataContract]
        public class SceneCollection : TrackingCollection<Scene>
        {
            Scene scene;

            public SceneCollection(Scene sceneParam)
            {
                scene = sceneParam;
            }

            /// <inheritdoc/>
            protected override void InsertItem(int index, Scene item)
            {
                if (item.Parent != null)
                    throw new InvalidOperationException("This scene already has a Parent. Detach it first.");

                item.parent = scene;
                base.InsertItem(index, item);
            }

            /// <inheritdoc/>
            protected override void RemoveItem(int index)
            {
                var item = this[index];
                if (item.Parent != scene)
                    throw new InvalidOperationException("This scene's parent is not the expected value.");

                item.parent = null;
                base.RemoveItem(index);
            }
        }
    }
}

View on GitHub (pinned to 96fad776d2)