stride3d/stride · error · InvalidOperationException
The given assetSidePart.Id does not correspond to any…
Error message
The given assetSidePart.Id does not correspond to any existing part.
What it means
UIEditorController.RemovePart throws this InvalidOperationException when assetSidePart.Id cannot be resolved to a game-side UIElement via FindPart. Removing an element with no game-side mirror is treated as a logic error rather than a no-op, because it indicates the asset-side and game-side trees have diverged.
Solutions
- Check that the part id exists in the view model tree before calling RemovePart.
- Make deletion idempotent on the caller side: track already-removed ids and skip repeats.
- Refresh id references after undo/redo or asset reload.
- Ensure AddPart succeeded before attempting to remove the same part.
Example fix
// before
controller.RemovePart(part, parent);
// after
if (removedIds.Add(part.Id))
controller.RemovePart(part, parent);
Defensive patterns
Strategy: validation
Validate before calling
bool partExists = viewModel.TreeRoot.Flatten().Any(e => e.Id == part.Id); if (!partExists) return; // nothing to remove, skip
Type guard
UIElementViewModel FindLivePart(Id id) => viewModel.TreeRoot.Flatten().FirstOrDefault(e => e.Id == id);
Try / catch
try { controller.RemovePart(part, parent); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not correspond to any existing part")) { /* already removed; ignore */ } Prevention
- Make delete commands idempotent (track already-removed ids).
- Debounce or guard duplicate delete events.
- Refresh id references after undo/redo or reload.
- Only remove parts whose add completed successfully.
When it happens
Trigger: Calling RemovePart with an id that was already removed, never added, or belongs to another asset; RemovePart invoked twice for the same element (duplicate delete events); game-side creation previously failed so the mirror entry is missing.
Common situations: Delete handlers firing twice, deletion during undo/redo replay with stale ids, scripts caching element ids across asset reloads.
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 parentId does not correspond to any existing part.
- 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/2b1288981cd6a73d.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/Services/UIEditorController.cs:256
}
GameSideNodeContainer.GetNode(contentControl)[nameof(contentControl.Content)].Update(gameSidePart);
}
}
});
}
/// <inheritdoc />
public override Task RemovePart([NotNull] UIHierarchyItemViewModel parent, UIElement assetSidePart)
{
EnsureAssetAccess();
return InvokeAsync(() =>
{
Logger.Debug($"Removing element {assetSidePart.Id} from game-side scene");
var partId = new AbsoluteId(AssetId.Empty, assetSidePart.Id);
var part = (UIElement)FindPart(partId);
if (part == null)
throw new InvalidOperationException($"The given {nameof(assetSidePart.Id)} does not correspond to any existing part.");
var parentId = (parent as UIElementViewModel)?.Id;
if (parentId == null)
{
RootElements.Remove(assetSidePart.Id);
}
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)
{
var i = panel.Children.IndexOf(part);
GameSideNodeContainer.GetNode(panel.Children).Remove(part, new NodeIndex(i));View on GitHub (pinned to 96fad776d2)