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
- 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)
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
- Keep IEntityFactory implementations returning single root entities
- Document the single-entity contract on custom factories
- Insert extra children explicitly after the root is created
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
- Replace, Move and Reset are not supported on this…
- and cannot both be empty.
- There must be two and only two input values for Int2.
- Indices for Int2 run from 0 to 1, inclusive.
- There must be three and only three input values for Int3.
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)