{"record":{"id":"63af2629628f2bcf","repo":"stride3d/stride","slug":"parent-cannot-be-null","errorCode":null,"errorMessage":"parent cannot be null","messagePattern":"parent cannot be null","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityFolderOperation.cs","lineNumber":92,"sourceCode":"            {\n                parent = parent?.Folders.FirstOrDefault(x => string.Equals(x.Name, folderPath[i], EntityFolderViewModel.FolderCase));\n            }\n            // Note: empty folders are not saved and can \"disappear\" after closing/reopening an editor.\n            // In order for action to be undo/redo-able we must allow the possibility to not find the folder.\n            EntityFolderViewModel folder;\n            switch (action)\n            {\n                case Action.FolderCreated:\n                    folder = parent?.Folders.FirstOrDefault(x => string.Equals(x.Name, folderName, EntityFolderViewModel.FolderCase));\n                    folder?.Delete();\n                    action = Action.FolderDeleted;\n                    break;\n                case Action.FolderDeleted:\n                    folder = parent?.Folders.FirstOrDefault(x => string.Equals(x.Name, folderName, EntityFolderViewModel.FolderCase));\n                    if (folder == null && editor != null)\n                    {\n                        // folder not found, let's recreate it\n                        if (parent == null) throw new InvalidOperationException($\"{nameof(parent)} cannot be null\");\n                        folder = editor.CreateFolder(asset, parent, false);\n                        folder.Name = folderName;\n                    }\n                    action = Action.FolderCreated;\n                    break;\n                case Action.FolderRenamed:\n                    folder = parent?.Folders.FirstOrDefault(x => string.Equals(x.Name, folderName, EntityFolderViewModel.FolderCase));\n                    if (folder != null)\n                    {\n                        folder.Name = oldFolderName;\n                    }\n                    folderPath[folderPath.Length - 1] = oldFolderName;\n                    oldFolderName = folderName;\n                    break;\n                default:\n                    throw new ArgumentOutOfRangeException();\n            }\n        }","sourceCodeStart":74,"sourceCodeEnd":110,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/AssetEditors/EntityHierarchyEditor/ViewModels/EntityFolderOperation.cs#L74-L110","documentation":"During Undo of a FolderDeleted operation, the code tries to locate the deleted folder's parent folder; if the parent reference is null it cannot recreate the folder and throws InvalidOperationException with 'parent cannot be null'.","triggerScenarios":"Undoing a folder deletion after the hierarchy was reloaded/changed so the resolved parent (parent?.Folders...) is null and the folder cannot be recreated under it.","commonSituations":"Undo stacks surviving asset reloads or scene switches; deleting a root-level folder whose parent lookup returns null; editor state desynchronized from disk after external modifications.","solutions":["Ensure undo operations are cleared when the asset/hierarchy is reloaded so stale operations are not replayed","Check why the parent folder no longer exists (asset externally modified) and reconcile state before undo","Guard undo of FolderDeleted with a check that the parent path still resolves","Recreate the missing parent folders before replaying the operation"],"exampleFix":"// before\nop.Undo(); // may throw if hierarchy reloaded\n// after\nif (op.ResolvesParent()) op.Undo(); else assetVm.ReloadOperations();","handlingStrategy":"try-catch","validationCode":"if (parent == null || !asset.Folders.Contains(parent)) { RefreshHierarchy(); return; }","typeGuard":"static bool CanUndoFolderDelete(EntityFolderOperation op) => op.ResolvesParent();","tryCatchPattern":"try { op.Undo(); }\ncatch (InvalidOperationException ex) { log.Warn(ex); editor.RefreshHierarchy(); }","preventionTips":["Clear undo stacks on asset reload","Refresh hierarchy state before replaying old undo operations","Avoid external modifications to asset folders while undo history is active"],"tags":["csharp","undo-redo","editor","null"],"backgroundTag":"internal-invariant-violation","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"}