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
- Flatten the menu so submenus contain only plain items (one nesting level total)
- Move deeper navigation into dedicated screens reached by selecting a submenu item
- 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
- Limit navigation bar menus to one submenu layer
- Move deeper hierarchy into content screens
- Automate a menu-depth check in CI
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
- %s does not support submenus
- Maximum number of items supported by %s is %d. Limit can be
- %d is not a valid view id
- Called setCheckedItem(MenuItem) with an item that is not in
- secondaryIconGravity cannot have the same alignment as iconG
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/e87c171d78a5fafc.
Report an issue: GitHub.