stride3d/stride · error · InvalidOperationException
The given parentId does not correspond to any existing part.
Error message
The given parentId does not correspond to any existing part.
What it means
UIEditorController.AddPart throws this InvalidOperationException when the parentId for a new UI part cannot be resolved to an existing game-side UIElement via FindPart. The controller maintains a game-side mirror of the asset hierarchy; attaching a child to an unknown parent would corrupt that mirror, so it fails fast.
Solutions
- Verify the parentId exists in the current UI hierarchy before calling AddPart.
- Create/register the parent part first so parent-before-child ordering holds.
- Re-fetch ids after undo/redo or asset reload; never cache ids across transactions.
- Confirm the AbsoluteId's asset id matches the currently loaded UI asset.
Example fix
// before
controller.AddPart(newPart, staleParentId);
// after
var parent = viewModel.TreeRoot.Flatten().FirstOrDefault(e => e.Id == staleParentId);
if (parent != null)
controller.AddPart(newPart, staleParentId);
Defensive patterns
Strategy: validation
Validate before calling
bool parentExists = viewModel.TreeRoot.Flatten().Any(e => e.Id == parentId);
if (!parentExists) throw new InvalidOperationException($"Parent {parentId} not in hierarchy"); Type guard
UIElementViewModel ResolveParent(AbsoluteId id) => viewModel.TreeRoot.Flatten().FirstOrDefault(e => e.Id == id);
Try / catch
try { controller.AddPart(newPart, parentId); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not correspond to any existing part")) {
// recreate parent or skip
} Prevention
- Validate parent ids against the live hierarchy before add operations.
- Enforce parent-before-child ordering when building parts.
- Never cache element ids across undo/redo or asset reloads.
- Check that the AbsoluteId's asset id matches the loaded asset.
When it happens
Trigger: Calling AddPart with a parentId that was never registered, was already removed by a prior RemovePart, belongs to a different asset (AbsoluteId asset-id mismatch), or whose game-side element was not yet created.
Common situations: Editor plugins/scripts reusing stale ids after undo/redo, out-of-order updates where the child is added before its parent, id collisions across assets.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- The given assetSidePart.Id does not correspond to any…
- The given element is not a child of this panel.
- The control corresponding to the given parentId is a…
- Changing the panel from a user library type is currently…
- Grouping elements into a user library type isn't supported.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/dd6263241186f88e.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs:225
public override Task AddPart([NotNull] UIHierarchyItemViewModel parent, UIElement assetSidePart)
{
EnsureAssetAccess();
var gameSidePart = ClonePartForGameSide(parent.Asset.Asset, assetSidePart);
return InvokeAsync(() =>
{
Logger.Debug($"Adding element {assetSidePart.Id} to game-side scene");
var parentId = (parent as UIElementViewModel)?.Id;
if (parentId == null)
{
RootElements[assetSidePart.Id] = gameSidePart;
}
else
{
var parentElement = (UIElement)FindPart(parentId.Value);
if (parentElement == null)
throw new InvalidOperationException($"The given {nameof(parentId)} does not correspond to any existing part.");
var panel = parentElement as Panel;
var contentControl = parentElement as ContentControl;
if (panel != null)
{
GameSideNodeContainer.GetNode(panel.Children).Add(gameSidePart);
}
else if (contentControl != null)
{
if (contentControl.Content != null)
{
throw new InvalidOperationException($"The control corresponding to the given {nameof(parentId)} is a ContentControl that already has a Content.");
}
GameSideNodeContainer.GetNode(contentControl)[nameof(contentControl.Content)].Update(gameSidePart);
}
}
});
}View on GitHub (pinned to 96fad776d2)