stride3d/stride · error · NotSupportedException

NotSupportedException

Error message

NotSupportedException

What it means

SceneViewModel.ChildrenCollectionChanged handles CollectionChanged notifications from the Children observable collection, syncing parent/child links and the underlying childrenNode list. It only supports Add, Remove and Replace actions; Move and Reset are treated as unsupported and throw NotSupportedException because the handler cannot incrementally reconstruct the parent-child state for them.

Solutions

  1. Replace Move/Reset operations with explicit Remove + Add calls on the Children collection at the correct indices.
  2. Wrap bulk structural changes in an undo/redo transaction (UndoRedoService) or set the updatingChildren guard so the handler early-returns.
  3. If Move/Reset support is needed, extend ChildrenCollectionChanged to rebuild childrenNode from the current Children state instead of throwing.

Example fix

// before
Children.Clear(); // raises Reset -> NotSupportedException
// after
foreach (var child in Children.ToList())
    Children.Remove(child); // raises Remove, which is handled
Defensive patterns

Strategy: try-catch

Validate before calling

if (e.Action == NotifyCollectionChangedAction.Move || e.Action == NotifyCollectionChangedAction.Reset)
    return; // or handle explicitly before mutating Children

Type guard

static bool IsSupported(e) => e is NotifyCollectionChangedEventArgs args &&
    (args.Action == NotifyCollectionChangedAction.Add ||
     args.Action == NotifyCollectionChangedAction.Remove ||
     args.Action == NotifyCollectionChangedAction.Replace);

Try / catch

try
{
    Children.Move(oldIndex, newIndex);
}
catch (NotSupportedException ex)
{
    // fall back to Remove+Add
    var item = Children[oldIndex];
    Children.RemoveAt(oldIndex);
    Children.Insert(newIndex, item);
}

Prevention

When it happens

Trigger: Raising CollectionChanged with e.Action == Move (e.g. Children.Move(...)) or Reset (e.g. calling Children.Clear() or raising Reset) outside of an undo/redo transaction and while updatingChildren is false.

Common situations: Reordering child scenes in the scene editor by moving items in the collection, clearing the whole Children collection at once, or custom editor code that resets an ObservableCollection instead of adding/removing items individually.

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/748a0d68769b2d8d. Report an issue: GitHub.

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/ViewModel/SceneViewModel.cs:277

                        if (e.NewItems?.Count > 0)
                        {
                            var index = e.NewStartingIndex;
                            foreach (var scene in e.NewItems.Cast<SceneViewModel>())
                            {
                                // Note: this can happen after a cut/paste when the parent/child relationship is fixed-up.
                                if (scene.Parent != this)
                                {
                                    scene.Parent?.Children.Remove(scene);
                                    scene.Parent = this;
                                }
                                childrenNode.Add(scene.Id, new NodeIndex(index++));
                            }
                        }
                        break;

                    case NotifyCollectionChangedAction.Move:
                    case NotifyCollectionChangedAction.Reset:
                        throw new NotSupportedException();
                    default:
                        throw new ArgumentOutOfRangeException();
                }
            }
            finally
            {
                updatingChildren = false;
            }
        }

        private void ChildrenNodeItemChanged(object sender, ItemChangeEventArgs e)
        {
            if (updatingChildren)
                return;

            try
            {
                updatingChildren = true;

View on GitHub (pinned to 96fad776d2)