stride3d/stride · error · InvalidOperationException

Entity factories should create single entity. Creating a…

Error message

Entity factories should create single entity. Creating a hierarchy is not supported.

What it means

CreateEntity in EntityHierarchyEditorViewModel only supports IEntityFactory implementations that return a single top-level entity. If the created entity already has transform children (a hierarchy), an InvalidOperationException is thrown, as noted by the TODO — hierarchy creation would need a different insertion API.

Solutions

  1. Modify the IEntityFactory implementation to return only a single root entity with no children
  2. Insert child entities separately after the root is created (AddPartToAsset / InsertAssetEntity)
  3. Change the factory interface and call sites to support hierarchies (as the TODO suggests)

Example fix

// before
var entity = factory.CreateEntity(); // entity has children
editorViewModel.CreateEntity(entity, parent);
// after
var entity = factory.CreateEntity();
editorViewModel.CreateEntity(entity, parent); // factory must not add children
// add children separately via AddPartToAsset if needed
Defensive patterns

Strategy: validation

Validate before calling

var entity = factory.CreateEntity();
if (entity.Transform.Children.Count == 0)
    editorViewModel.CreateEntity(entity, parent);

Try / catch

try { editorViewModel.CreateEntity(entity, parent); }
catch (InvalidOperationException) { /* factory produced a hierarchy; split it */ }

Prevention

When it happens

Trigger: Invoking an entity factory (IEntityFactory) whose CreateEntity builds an entity with child transforms, then passing the result to CreateEntity.

Common situations: Custom entity factories from plugins/asset imports that spawn prefab-like parent+children structures; upgrading a factory to produce compound entities without updating insertion code.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityHierarchyEditorViewModel.cs:410

        {
            if (parent == null) throw new ArgumentNullException(nameof(parent));

            var entity = factory != null ? await factory.CreateEntity(parent) : new Entity { Name = EntityFactory.ComputeNewName(parent, "Entity") };

            if (entity != null)
            {
                // Create item ids collections for new entity before actually adding them to the asset.
                AssetCollectionItemIdHelper.GenerateMissingItemIds(entity);

                if (atMousePosition)
                {
                    var position = Controller.GetMousePositionInScene(true);
                    entity.Transform.Position = position;
                }

                // TODO: this can be easily supported by calling the other override of InsertAssetEntity. IEntityFactory and all implementations must be modified to return a hierarchy
                if (entity.Transform.Children.Count > 0)
                    throw new InvalidOperationException("Entity factories should create single entity. Creating a hierarchy is not supported.");

                var collection = new AssetPartCollection<EntityDesign, Entity> { new EntityDesign(entity, (parent as EntityFolderViewModel)?.Path ?? "") };

                using (var transaction = UndoRedoService.CreateTransaction())
                {
                    parent.Asset.AssetHierarchyPropertyGraph.AddPartToAsset(collection, collection.Single().Value, (parent.Owner as EntityViewModel)?.AssetSideEntity, parent.Owner.EntityCount);
                    UndoRedoService.SetName(transaction, $"Create entity '{entity.Name}'");
                }
                // Select the newly created entity
                var partId = new AbsoluteId(parent.Asset.Id, entity.Id);
                var newEntity = (EntityViewModel)FindPartViewModel(partId);
                ClearSelection();
                SelectedContent.Add(newEntity);
                newEntity.IsEditing = true;
            }
        }

        [NotNull]

View on GitHub (pinned to 96fad776d2)