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

  1. Confirm the part was successfully added game-side before attempting removal.
  2. Guard with a FindPart check and skip removal when the part is absent (idempotent delete).
  3. 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

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


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)