dotnet/wpf · error

' ' can only host a ' ' or a ' '. ' ' is an invalid…

Error message

'{0}' can only host a '{1}' or a '{2}'. '{3}' is an invalid container.

What it means

MenuItem validates its item containers: only MenuItem and Separator are legal children, since menu item containers must be menu items or separators. When the container resolution path encounters a container of any other type, it throws InvalidOperationException naming the host type, the two allowed types, and the offending container's type.

Solutions

  1. Add only MenuItem or Separator children; convert other objects into MenuItems (set Header for text).
  2. When data-binding, supply ItemContainerStyle or an ItemContainerTemplate so each data item is wrapped in a MenuItem.
  3. Put arbitrary content inside MenuItem.Header instead of adding it as a direct child item.
  4. If you need specialized containers, derive them from MenuItem so the type check passes.

Example fix

// before: menuItem.Items.Add(new Button { Content = "Click" }); // throws // after: menuItem.Items.Add(new MenuItem { Header = "Click" });
Defensive patterns

Strategy: type-guard

Validate before calling

static bool IsValidMenuItemChild(object item) => item is MenuItem || item is Separator;

Type guard

bool IsMenuContainer(DependencyObject c) => c is MenuItem || c is Separator;

Try / catch

try { menuItem.Items.Add(child); } catch (InvalidOperationException ex) when (ex.Message.Contains("invalid container")) { menuItem.Items.Add(new MenuItem { Header = child.ToString() }); }

Prevention

When it happens

Trigger: Adding a non-MenuItem/non-Separator object (raw string, Button, TextBlock, custom control) to MenuItem.Items; or data-binding ItemsSource without an ItemContainerStyle/ItemContainerTemplate so the generated container is not a MenuItem, causing the check 'itemContainer is MenuItem || itemContainer is Separator' to fail.

Common situations: Binding MenuItem.ItemsSource to plain view-model objects without a container mapping; placing Label/Button/TextBlock children directly inside a MenuItem in XAML; custom control templates that generate foreign containers.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/9614bc4d63f3839d. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/MenuItem.cs:2101

        /// <summary> Create or identify the element used to display the given item. </summary>
        protected override DependencyObject GetContainerForItemOverride()
        {
            object currentItem = _currentItem;
            _currentItem = null;

            if (UsesItemContainerTemplate)
            {
                DataTemplate itemContainerTemplate = ItemContainerTemplateSelector.SelectTemplate(currentItem, this);
                if (itemContainerTemplate != null)
                {
                    object itemContainer = itemContainerTemplate.LoadContent();
                    if (itemContainer is MenuItem || itemContainer is Separator)
                    {
                        return itemContainer as DependencyObject;
                    }
                    else
                    {
                        throw new InvalidOperationException(SR.Format(SR.InvalidItemContainer, this.GetType().Name, nameof(MenuItem), nameof(Separator), itemContainer));
                    }
                }
            }

            return new MenuItem();
        }

        /// <summary>
        ///     Called when the parent of the Visual has changed.
        /// </summary>
        /// <param name="oldParent">Old parent or null if the Visual did not have a parent before.</param>
        protected internal override void OnVisualParentChanged(DependencyObject oldParent)
        {
            base.OnVisualParentChanged(oldParent);
            UpdateRole();

            // Windows OS bug:1988393; DevDiv bug:107459
            // MenuItem template contains ItemsPresenter where Grid.IsSharedSizeScope="true" and need to inherits PrivateSharedSizeScopeProperty value

View on GitHub (pinned to 81131a70a4)