stride3d/stride · error · InvalidOperationException
Can't change the parent of this folder
Error message
Can't change the parent of this folder
What it means
DirectoryBaseViewModel.SetParent is the single hook used by the Parent property setter to reparent a directory node in the asset editor's folder tree. It is only valid for concrete DirectoryViewModel instances; other subclasses (e.g. MountPointViewModel) have fixed or null parents, so the method throws InvalidOperationException to refuse the operation.
Solutions
- Only invoke SetParent (or set Parent) on instances of DirectoryViewModel
- Guard with a type check before reparenting
- Use the mount point's dedicated APIs instead of reparenting it
Example fix
// before
node.Parent = newParent;
// after
if (node is DirectoryViewModel dir) { dir.Parent = newParent; } Defensive patterns
Strategy: type-guard
Validate before calling
if (node is not DirectoryViewModel) throw new ArgumentException("Only DirectoryViewModel can be reparented"); Type guard
bool CanReparent(DirectoryBaseViewModel n) => n is DirectoryViewModel;
Try / catch
try { node.Parent = newParent; } catch (InvalidOperationException) { /* node is not a real directory */ } Prevention
- Type-check DirectoryViewModel before reparenting
- Never set Parent on mount points
- Centralize tree mutations in one guarded helper
When it happens
Trigger: Calling SetParent on a DirectoryBaseViewModel subclass that is not a DirectoryViewModel — typically by assigning the Parent property of a MountPointViewModel or another non-DirectoryViewModel node instead of a real folder.
Common situations: Custom editor plugins or tree-manipulation code that walks the directory hierarchy generically and tries to move/attach any DirectoryBaseViewModel node, accidentally targeting a mount point or other special node.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The folder being deleted is not empty.
- entity must contain a non-null asset entity.
- A dependency object must be attached in order to register a…
- A dependency object must be attached in order to unregister…
- No handler was previously registered for this dependency…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4a5369b9702701eb.
Report an issue: GitHub.
Appendix: source
Thrown at sources/editor/Stride.Core.Assets.Editor/ViewModel/DirectoryBaseViewModel.cs:167
var directoryNames = path.Split(Separator.ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
result = directoryNames.Aggregate(result, (current, next) => current.SubDirectories.FirstOrDefault(x => string.Equals(next, x.Name, StringComparison.InvariantCultureIgnoreCase)) ?? new DirectoryViewModel(next, current, canUndoRedoCreation));
}
return result;
}
public abstract bool CanDelete(out string error);
public abstract void Delete();
/// <summary>
/// Set the parent of this directory and properly update <see cref="SubDirectories"/> collection of the previous and the new parent.
/// </summary>
/// <remarks>Should be invoked only by the setter of <see cref="Parent"/>.</remarks>
/// <param name="oldParent">The old parent of this directory.</param>
/// <param name="newParent">The nwe parent of this directory.</param>
protected void SetParent(DirectoryBaseViewModel oldParent, DirectoryBaseViewModel newParent)
{
if (this is not DirectoryViewModel directory) throw new InvalidOperationException("Can't change the parent of this folder");
Dispatcher.Invoke(() =>
{
oldParent?.subDirectories.Remove(directory);
if (newParent != null)
{
newParent.subDirectories.Add(directory);
UpdateAssetUrls();
}
});
}
protected void UpdateAssetUrls()
{
var hierarchy = new List<DirectoryBaseViewModel>();
GetDirectoryHierarchy(hierarchy);
View on GitHub (pinned to 96fad776d2)