stride3d/stride · error · InvalidOperationException
The given does not correspond to any existing part.
Error message
The given {nameof(assetSidePart.Id)} does not correspond to any existing part. What it means
SceneEditorController.RemovePart resolves the part to remove by constructing AbsoluteId(parent.Id.AssetId, assetSidePart.Id) and finding it game-side. It throws InvalidOperationException when that composite id matches no registered part, preventing removal of a non-existent game-side entity.
Solutions
- Confirm the part was successfully added game-side before attempting removal.
- Guard with a FindPart check and skip removal when the part is absent (idempotent delete).
- Refresh ids after asset reload so the composite AbsoluteId matches the registered part.
Example fix
// before
controller.RemovePart(parentViewModel, partViewModel); // may throw if not loaded
// after
var partId = new AbsoluteId(parentViewModel.Id.AssetId, partViewModel.Id);
if (controller.FindPart(partId) != null)
controller.RemovePart(parentViewModel, partViewModel); Defensive patterns
Strategy: validation
Validate before calling
var partId = new AbsoluteId(parent.Id.AssetId, part.Id);
if (controller.FindPart(partId) == null)
return; // already removed or never loaded
await controller.RemovePart(parent, part); Type guard
static bool PartExists(SceneEditorController c, AbsoluteId id) => c.FindPart(id) != null;
Try / catch
try { await controller.RemovePart(parent, part); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not correspond to any existing part")) { log.Debug("Part already absent game-side; treating delete as idempotent."); } Prevention
- Make deletes idempotent — skip when FindPart returns null.
- Avoid duplicate delete dispatches for the same part id.
- Refresh part ids after asset reload before deleting.
When it happens
Trigger: RemovePart called where FindPart(new AbsoluteId(parent.Id.AssetId, assetSidePart.Id)) returns null — the asset-side part id does not correspond to any game-side entity (e.g. entity not yet loaded or already removed).
Common situations: Deleting an entity whose game-side representation was never created (add failed earlier or scene not loaded); duplicate delete events; asset ids changed after re-import.
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 does not correspond to any existing part.
- Cannot change the name of a
- No scene match the given
- Simulated GamePad does not exist
- Simulated Keyboard does not exist
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/d28ec23894341838.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/SceneEditor/Services/SceneEditorController.cs:80
GameSideNodeContainer.GetNode(parentEntity.Transform.Children).Add(gameSidePart.Transform);
}
});
}
/// <inheritdoc />
/// <seealso cref="SceneEditorGame.UnloadEntity"/>
public override Task RemovePart([NotNull] EntityHierarchyElementViewModel parent, Entity assetSidePart)
{
EnsureAssetAccess();
return InvokeAsync(() =>
{
Logger.Debug($"Removing entity {assetSidePart.Id} from game-side scene");
var partId = new AbsoluteId(parent.Id.AssetId, assetSidePart.Id);
var part = (Entity)FindPart(partId);
if (part == null)
throw new InvalidOperationException($"The given {nameof(assetSidePart.Id)} does not correspond to any existing part.");
if (parent is SceneRootViewModel)
{
Game.UnloadEntity(part, parent.Id.ObjectId);
}
else
{
var parentEntity = (Entity)FindPart(parent.Id);
if (parentEntity == null)
throw new InvalidOperationException($"The given {nameof(parent.Id)} does not correspond to any existing part.");
var i = parentEntity.Transform.Children.IndexOf(part.Transform);
GameSideNodeContainer.GetNode(parentEntity.Transform.Children).Remove(part.Transform, new NodeIndex(i));
}
});
}
/// <summary>View on GitHub (pinned to 96fad776d2)