stride3d/stride · error · InvalidOperationException

A category cannot be deleted

Error message

A category cannot be deleted

What it means

CategoryViewModel represents an organizational category node in the asset tree, not a deletable entity. Its UpdateIsDeletedStatus override throws InvalidOperationException if something marks it as deleted. This is an internal invariant: only leaf items can be deleted, categories are structural nodes.

Solutions

  1. Filter selection to deletable item view models before deleting; skip nodes whose IsEditable/CanDelete indicates a category.
  2. Handle CanDelete returning false instead of forcing delete on category nodes.
  3. Call delete operations only on concrete asset/directory view models, not on CategoryViewModel instances.

Example fix

// before
foreach (var node in selectedNodes) node.Delete();
// after
foreach (var node in selectedNodes.OfType<AssetViewModel>()) node.Delete();
Defensive patterns

Strategy: validation

Validate before calling

if (node is CategoryViewModel) { logger.Info("Categories cannot be deleted"); return; }

Type guard

bool IsDeletableNode(object node) => node is not CategoryViewModel;

Try / catch

try { node.Delete(); }
catch (InvalidOperationException ex) when (ex.Message.Contains("category")) { logger.Warn("Cannot delete a category node; delete its items instead"); }

Prevention

When it happens

Trigger: Invoking delete logic on a CategoryViewModel — e.g. generic delete handlers that iterate all selected tree nodes including categories, or code setting IsDeleted on a category.

Common situations: Selecting a whole category in the editor and pressing Delete; batch-deletion scripts that do not filter tree-node types.

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


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/f33c6628a7427134. Report an issue: GitHub.

Appendix: source

Thrown at sources/editor/Stride.Core.Assets.Editor/ViewModel/CategoryViewModel.cs:41

        {
            Name = name;
            Content = new SortedObservableCollection<TChildren>(childComparer);
        }

        public sealed override string Name { get; set; }

        public SortedObservableCollection<TChildren> Content { get; }

        public override bool IsEditable => false;

        IEnumerable ICategoryViewModel.Content => Content;

        public override string TypeDisplayName => "Category";

        protected override void UpdateIsDeletedStatus()
        {
            if (IsDeleted)
                throw new InvalidOperationException("A category cannot be deleted");
        }
    }

    public abstract class CategoryViewModel<TParent, TChildren> : CategoryViewModel<TChildren>
    {
        protected CategoryViewModel(string name, TParent parent, SessionViewModel session, IComparer<TChildren> childComparer = null)
            : base(name, session, childComparer)
        {
            Parent = parent;
        }

        public TParent Parent { get; }
    }

    public class PackageCategoryViewModel : CategoryViewModel<PackageViewModel>, IChildViewModel
    {
        public PackageCategoryViewModel(string name, SessionViewModel session, IComparer<PackageViewModel> childComparer = null)
            : base(name, session, childComparer)

View on GitHub (pinned to 96fad776d2)