stride3d/stride · error · InvalidOperationException

This operation can only be executed on a selection of…

Error message

This operation can only be executed on a selection of sibling elements.

What it means

Thrown by UIEditorBaseViewModel when a group operation (e.g. wrapping the selection into a new Panel) is executed on a selection whose elements do not all share the same parent. The editor groups SelectedItems by comparing each item's Parent; if more than one distinct parent UIHierarchyItemViewModel exists, the operation is invalid because only siblings can be re-parented into a single new panel together.

Solutions

  1. Select only elements that are direct children of the same parent before running the group command.
  2. Group elements one branch at a time: group siblings within a panel first, then group the resulting panels.
  3. If scripting, filter SelectedItems so that all items satisfy item.Parent == first.Parent before invoking the operation.

Example fix

// before
viewModel.SelectedItems = mixedSelection; // elements with different parents
viewModel.GroupIntoPanel(typeof(Grid));
// after
var parent = ((UIHierarchyItemViewModel)mixedSelection[0]).Parent;
viewModel.SelectedItems = mixedSelection.Cast<UIHierarchyItemViewModel>().Where(x => x.Parent == parent).ToList();
viewModel.GroupIntoPanel(typeof(Grid));
Defensive patterns

Strategy: validation

Validate before calling

bool selectionIsSiblings = selectedItems.Cast<UIHierarchyItemViewModel>().Select(x => x.Parent).Distinct().Count() <= 1;

Type guard

static bool AreSiblings(IEnumerable<UIHierarchyItemViewModel> items) => items.Select(x => x.Parent).Distinct().Count() <= 1;

Try / catch

try { viewModel.GroupIntoPanel(typeof(Grid)); } catch (InvalidOperationException ex) { /* prompt: select only sibling elements */ }

Prevention

When it happens

Trigger: Calling the group-into-panel command in the UI editor with SelectedItems containing elements from different containers/panels, e.g. multi-selecting one element inside PanelA and another inside PanelB then invoking the grouping action.

Common situations: Multi-selecting UI elements across different branches of the visual tree with ctrl+click and then using a 'group' or 'wrap in panel' command; scripted editor automation that fills SelectedItems without checking hierarchy.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/UIEditor/ViewModels/UIEditorBaseViewModel.cs:603

            return Controller.AdornerService.GetElementIdsAtPosition(ref worldPosition).Select(id => FindPartViewModel(new AbsoluteId(Asset.Id, id))).OfType<UIElementViewModel>();
        }

        private void GroupInto(IUIElementFactory factory)
        {
            var targetPanelType = (factory as UIElementFromSystemLibrary)?.Type;
            if (targetPanelType == null)
                throw new NotSupportedException("Grouping elements into a user library type isn't supported.");
            if (!typeof(Panel).IsAssignableFrom(targetPanelType))
                throw new ArgumentException(@"The target type isn't a panel", nameof(targetPanelType));

            if (SelectedContent.Count == 0)
                return;

            // Ensure that the selected elements are sibling.
            var allParents = SelectedItems.Select(x => x.Parent).OfType<UIHierarchyItemViewModel>().ToList();
            var parent = allParents[0];
            if (allParents.Any(x => x != parent))
                throw new InvalidOperationException("This operation can only be executed on a selection of sibling elements.");

            using (var transaction = UndoRedoService.CreateTransaction())
            {
                var children = SelectedItems.ToList();
                // Create the new panel into which we'll insert the selection
                var newPanel = (Panel)Activator.CreateInstance(targetPanelType);
                var newPanelDesign = new UIElementDesign(newPanel);
                // Create a hierarchy containing all children and the panel
                var hierarchy = UIAssetPropertyGraph.CloneSubHierarchies(Asset.Session.AssetNodeContainer, Asset.Asset, children.Select(c => c.Id.ObjectId), SubHierarchyCloneFlags.None, out _);
                hierarchy.RootParts.Add(newPanel);
                hierarchy.Parts.Add(newPanelDesign);
                // Remove all children from their partDesign panel.
                foreach (var child in children)
                {
                    child.Asset.AssetHierarchyPropertyGraph.RemovePartFromAsset(child.UIElementDesign);
                }
                // Add the new panel in place of the selected content.
                parent.Asset.InsertUIElement(hierarchy.Parts, newPanelDesign, (parent as UIElementViewModel)?.AssetSideUIElement);

View on GitHub (pinned to 96fad776d2)