material-components/material-components-android · error · IllegalArgumentException

Only one layer of submenu is supported; a submenu inside a s

Error message

Only one layer of submenu is supported; a submenu inside a submenu is not supported by the Navigation Bar.

What it means

While building item views from the menu, NavigationBarMenuView throws IllegalArgumentException if it encounters a submenu item while still expecting subheader children from a previous submenu — i.e. nested submenus. The expanded navigation bar supports exactly one layer of submenu; a submenu declared inside another submenu's items is rejected at layout time.

Source

Thrown at lib/java/com/google/android/material/navigation/NavigationBarMenuView.java:1226

    int menuSize = menu.size();
    buttons = new NavigationBarMenuItemView[menuSize];
    int collapsedItemsSoFar = 0;
    int nextSubheaderItemCount = 0;
    boolean shifting =
        isShifting(labelVisibilityMode, getCurrentVisibleContentItemCount());
    for (int i = 0; i < menuSize; i++) {
      MenuItem menuItem = menu.getItemAt(i);
      NavigationBarMenuItemView child;
      if (menuItem instanceof DividerMenuItem) {
        // Add a divider
        child = new NavigationBarDividerView(getContext());
        child.setOnlyShowWhenExpanded(true);
        ((NavigationBarDividerView) child).setDividersEnabled(dividersEnabled);
      } else if (menuItem.hasSubMenu()) {
        if (nextSubheaderItemCount > 0) {
          // We do not support submenus inside submenus. If there is still subheader items to be
          // instantiated, we should not have another submenu.
          throw new IllegalArgumentException(
              "Only one layer of submenu is supported; a submenu "
                  + "inside a submenu is not supported by the Navigation Bar.");
        }
        // Add subheader item
        child = new NavigationBarSubheaderView(getContext());
        ((NavigationBarSubheaderView) child).
            setTextAppearance(horizontalItemTextAppearanceActive != 0
                ? horizontalItemTextAppearanceActive : itemTextAppearanceActive);
        ((NavigationBarSubheaderView) child).setTextColor(itemTextColorFromUser);
        child.setOnlyShowWhenExpanded(true);
        child.initialize((MenuItemImpl) menuItem, 0);
        nextSubheaderItemCount = menuItem.getSubMenu().size();
      } else if (nextSubheaderItemCount > 0) { // Add submenu items
        child =
            createMenuItem(i, (MenuItemImpl) menuItem, shifting, /* hideWhenCollapsed= */ true);
        nextSubheaderItemCount--;
      } else {
        child =

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Flatten the menu so submenus contain only plain items (one nesting level total)
  2. Move deeper navigation into dedicated screens reached by selecting a submenu item
  3. Lint-check menu XMLs for <menu> nested more than one level deep when used with navigation bars

Example fix

<!-- before -->
<item android:title="Section">
  <menu>
    <item android:title="Sub" >
      <menu><item android:title="Deep"/></menu>
    </item>
  </menu>
</item>
<!-- after -->
<item android:title="Section">
  <menu>
    <item android:title="Sub"/>
    <item android:title="Deep"/>
  </menu>
</item>
Defensive patterns

Strategy: validation

Validate before calling

// Static check: reject menu XMLs with two-level nesting
fun maxMenuDepth(parser: XmlPullParser): Int {
    var depth = 0; var max = 0
    while (parser.next() != XmlPullParser.END_DOCUMENT) {
        if (parser.eventType == XmlPullParser.START_TAG && parser.name == "menu") max = maxOf(max, ++depth)
        if (parser.eventType == XmlPullParser.END_TAG && parser.name == "menu") depth--
    }
    return max
}

Try / catch

catch (e: IllegalArgumentException) { Log.e(TAG, "Nested submenus unsupported; flattening menu", e); inflateFlatMenu() }

Prevention

When it happens

Trigger: A menu XML applied to a navigation bar with submenu support enabled where an <item> inside a nested <menu> itself contains another <menu>; the loop sees menuItem.hasSubMenu() while nextSubheaderItemCount > 0 and throws.

Common situations: Deeply nested drawer-style menus reused in NavigationBarView with expanded menu support; menu files authored for NavigationView with two-level nesting.

Related errors


AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14). Data as JSON: /api/errors/e87c171d78a5fafc. Report an issue: GitHub.