{"record":{"id":"457efd9050278812","repo":"stride3d/stride","slug":"entity-factories-should-create-single-entity-creating-a","errorCode":null,"errorMessage":"Entity factories should create single entity. Creating a hierarchy is not supported.","messagePattern":"Entity factories should create single entity\\. Creating a hierarchy is not supported\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityHierarchyEditorViewModel.cs","lineNumber":410,"sourceCode":"        {\n            if (parent == null) throw new ArgumentNullException(nameof(parent));\n\n            var entity = factory != null ? await factory.CreateEntity(parent) : new Entity { Name = EntityFactory.ComputeNewName(parent, \"Entity\") };\n\n            if (entity != null)\n            {\n                // Create item ids collections for new entity before actually adding them to the asset.\n                AssetCollectionItemIdHelper.GenerateMissingItemIds(entity);\n\n                if (atMousePosition)\n                {\n                    var position = Controller.GetMousePositionInScene(true);\n                    entity.Transform.Position = position;\n                }\n\n                // TODO: this can be easily supported by calling the other override of InsertAssetEntity. IEntityFactory and all implementations must be modified to return a hierarchy\n                if (entity.Transform.Children.Count > 0)\n                    throw new InvalidOperationException(\"Entity factories should create single entity. Creating a hierarchy is not supported.\");\n\n                var collection = new AssetPartCollection<EntityDesign, Entity> { new EntityDesign(entity, (parent as EntityFolderViewModel)?.Path ?? \"\") };\n\n                using (var transaction = UndoRedoService.CreateTransaction())\n                {\n                    parent.Asset.AssetHierarchyPropertyGraph.AddPartToAsset(collection, collection.Single().Value, (parent.Owner as EntityViewModel)?.AssetSideEntity, parent.Owner.EntityCount);\n                    UndoRedoService.SetName(transaction, $\"Create entity '{entity.Name}'\");\n                }\n                // Select the newly created entity\n                var partId = new AbsoluteId(parent.Asset.Id, entity.Id);\n                var newEntity = (EntityViewModel)FindPartViewModel(partId);\n                ClearSelection();\n                SelectedContent.Add(newEntity);\n                newEntity.IsEditing = true;\n            }\n        }\n\n        [NotNull]","sourceCodeStart":392,"sourceCodeEnd":428,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityHierarchyEditorViewModel.cs#L392-L428","documentation":"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.","triggerScenarios":"Invoking an entity factory (IEntityFactory) whose CreateEntity builds an entity with child transforms, then passing the result to CreateEntity.","commonSituations":"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.","solutions":["Modify the IEntityFactory implementation to return only a single root entity with no children","Insert child entities separately after the root is created (AddPartToAsset / InsertAssetEntity)","Change the factory interface and call sites to support hierarchies (as the TODO suggests)"],"exampleFix":"// before\nvar entity = factory.CreateEntity(); // entity has children\neditorViewModel.CreateEntity(entity, parent);\n// after\nvar entity = factory.CreateEntity();\neditorViewModel.CreateEntity(entity, parent); // factory must not add children\n// add children separately via AddPartToAsset if needed","handlingStrategy":"validation","validationCode":"var entity = factory.CreateEntity();\nif (entity.Transform.Children.Count == 0)\n    editorViewModel.CreateEntity(entity, parent);","typeGuard":null,"tryCatchPattern":"try { editorViewModel.CreateEntity(entity, parent); }\ncatch (InvalidOperationException) { /* factory produced a hierarchy; split it */ }","preventionTips":["Keep IEntityFactory implementations returning single root entities","Document the single-entity contract on custom factories","Insert extra children explicitly after the root is created"],"tags":["csharp","stride","entity-factory","unsupported"],"backgroundTag":"unsupported-operation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}