{"record":{"id":"2eefa02b4777b6ce","repo":"stride3d/stride","slug":"scenes-with-child-scenes-cannot-be-removed","errorCode":null,"errorMessage":"Scenes with child scenes cannot be removed.","messagePattern":"Scenes with child scenes cannot be removed\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/AssetEditors/SceneEditor/Game/SceneEditorGame.cs","lineNumber":89,"sourceCode":"        }\n\n        /// <summary>\n        /// Removes the existing scene identified by <paramref name=\"sceneId\"/>.\n        /// </summary>\n        /// <param name=\"sceneId\">The identifier of the scene to remove.</param>\n        /// <remarks>\n        /// The scene must be empty, i.e. its child scenes must have been removed first and its entities unloaded.\n        /// </remarks>\n        public void RemoveScene(Guid sceneId)\n        {\n            if (sceneId == Guid.Empty)\n                throw new InvalidOperationException($\"{nameof(sceneId)} cannot be {nameof(Guid.Empty)}.\");\n\n            EnsureContentScene();\n\n            var scene = GetScene(sceneId);\n            if (scene.Children.Count > 0)\n                throw new InvalidOperationException(\"Scenes with child scenes cannot be removed.\");\n            if (scene.Entities.Count > 0)\n                throw new InvalidOperationException(\"Scenes with entities cannot be removed.\");\n\n            SceneRemoved?.Invoke(scene);\n            RemoveSceneFromParent(scene);\n            scenes.Remove(sceneId);\n        }\n\n        /// <inheritdoc/>\n        public override Entity FindSubEntity(Guid sceneId, Guid entityId)\n        {\n            EnsureContentScene();\n\n            Scene scene;\n            if (scenes.TryGetValue(sceneId, out scene))\n            {\n                Entity entity;\n                // Note: special case of the virtual anchor (sceneID == entityId), own by the parent scene","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/AssetEditors/SceneEditor/Game/SceneEditorGame.cs#L71-L107","documentation":"SceneEditorGame.RemoveScene throws this InvalidOperationException when the target scene still has child scenes. The API requires bottom-up deletion: children must be removed first, as noted in the method's remarks.","triggerScenarios":"Calling RemoveScene on a scene whose Children collection is non-empty.","commonSituations":"Deleting a parent scene in a hierarchy UI without deleting descendants; bulk cleanup that iterates scenes in arbitrary order.","solutions":["Recursively remove child scenes before removing the parent.","Iterate scene collections deepest-first when cleaning up.","Catch InvalidOperationException and prompt the user to delete children first."],"exampleFix":"// before\nsceneEditorGame.RemoveScene(sceneId); // has children\n// after\nvoid RemoveRecursive(Guid id) {\n    var scene = sceneEditorGame.GetScene(id);\n    foreach (var child in scene.Children.ToList())\n        RemoveRecursive(child.Id);\n    sceneEditorGame.RemoveScene(id);\n}","handlingStrategy":"try-catch","validationCode":"var scene = game.GetScene(sceneId);\nif (scene != null && scene.Children.Count > 0) RemoveChildrenFirst(scene);","typeGuard":null,"tryCatchPattern":"try { game.RemoveScene(sceneId); } catch (InvalidOperationException ex) when (ex.Message.Contains(\"child scenes\")) { DeleteChildrenRecursively(sceneId); game.RemoveScene(sceneId); }","preventionTips":["Always delete hierarchies bottom-up","Enumerate children before parents in cleanup code","Disable parent deletion in UI until children are removed"],"tags":["stride-editor","scene","hierarchy","invalid-state-transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}