stride3d/stride · error · InvalidOperationException

The entity to insert has already been destroyed

Error message

The entity to insert has already been destroyed

What it means

EntityHierarchyItemViewModel.InsertEntityViewModel refuses to insert an EntityViewModel flagged as destroyed (IsDestroyed), since re-parenting a destroyed view-model would corrupt the hierarchy. It throws InvalidOperationException before any mutation.

Solutions

  1. Create a fresh entity instead of reinserting a destroyed one
  2. Check entity.IsDestroyed before calling InsertEntityViewModel and skip or recreate
  3. Fix undo/redo logic to recreate view-models rather than reuse destroyed instances

Example fix

// before
parent.InsertEntityViewModel(entity, index); // throws if destroyed
// after
if (!entity.IsDestroyed)
    parent.InsertEntityViewModel(entity, index);
Defensive patterns

Strategy: validation

Validate before calling

if (!entity.IsDestroyed)
    parent.InsertEntityViewModel(entity, index);

Type guard

bool IsInsertable(EntityViewModel e) => !e.IsDestroyed;

Try / catch

try { parent.InsertEntityViewModel(entity, index); }
catch (InvalidOperationException) { /* recreate the entity view-model */ }

Prevention

When it happens

Trigger: Calling InsertEntityViewModel with an entity that was previously destroyed (e.g. via Destroy() or an undo/redo delete) but whose reference is still held and reused.

Common situations: Caching entity view-models across delete operations; undo/redo scripts that reinsert entities captured before destruction; double-processing of a delete-then-insert sequence.

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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityHierarchyItemViewModel.cs:230

                // Make sure to mark the position node as overridden if this entity has a base.
                var positionNode = (IAssetMemberNode)Editor.NodeContainer.GetNode(entity.Transform)[nameof(TransformComponent.Position)];
                if (positionNode.BaseNode != null)
                {
                    positionNode.OverrideContent(true);
                }
                // Add newly created entity to the result
                if (Editor.FindPartViewModel(new AbsoluteId(Asset.Id, entity.Id)) is EntityViewModel viewmodel)
                    result.Add(viewmodel);
            }

            return result;
        }

        internal void InsertEntityViewModel([NotNull] EntityViewModel entity, int index, bool expand = true)
        {
            if (entity.IsDestroyed)
                throw new InvalidOperationException("The entity to insert has already been destroyed");

            // Add the view model first, so actual entities can be fetched
            if (index < 0)
            {
                subEntities.Add(entity);
            }
            else
            {
                subEntities.Insert(index, entity);
            }

            if (expand)
            {
                IsExpanded = true;
            }
        }

        internal static void RemoveEntityViewModel([NotNull] EntityViewModel entity)

View on GitHub (pinned to 96fad776d2)