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

Tab belongs to a different TabLayout.

Error message

Tab belongs to a different TabLayout.

What it means

TabLayout.Tab objects are created by and owned by a specific TabLayout (tab.parent is set in newTab()). addTab(tab, position, setSelected) throws IllegalArgumentException if the tab was created by a different TabLayout instance, because tab views and position bookkeeping are per-layout.

Source

Thrown at lib/java/com/google/android/material/tabs/TabLayout.java:866

   * Add a tab to this layout. The tab will be added at the end of the list.
   *
   * @param tab Tab to add
   * @param setSelected True if the added tab should become the selected tab.
   */
  public void addTab(@NonNull Tab tab, boolean setSelected) {
    addTab(tab, tabs.size(), setSelected);
  }

  /**
   * Add a tab to this layout. The tab will be inserted at <code>position</code>.
   *
   * @param tab The tab to add
   * @param position The new position of the tab
   * @param setSelected True if the added tab should become the selected tab.
   */
  public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
    if (tab.parent != this) {
      throw new IllegalArgumentException("Tab belongs to a different TabLayout.");
    }
    configureTab(tab, position);
    addTabView(tab);

    if (setSelected) {
      tab.select();
    }
  }

  private void addTabFromItemView(@NonNull TabItem item) {
    final Tab tab = newTab();
    if (item.text != null) {
      tab.setText(item.text);
    }
    if (item.icon != null) {
      tab.setIcon(item.icon);
    }
    if (item.customLayout != 0) {

View on GitHub (pinned to ac7e18efee)

Solutions

  1. Create every tab from the same TabLayout that will display it: tabLayout.addTab(tabLayout.newTab().setText(...)).
  2. Audit helper/factory methods to make sure the TabLayout used for newTab() is the one used for addTab().
  3. If tabs move between layouts, remove from the original layout and recreate with newTab() on the target layout.

Example fix

// before
Tab tab = topTabs.newTab().setText("A");
bottomTabs.addTab(tab, 0, true); // throws

// after
bottomTabs.addTab(bottomTabs.newTab().setText("A"), 0, true);
Defensive patterns

Strategy: validation

Validate before calling

// Tab ownership has no public getter; enforce it structurally:
private static void addTabSafe(@NonNull TabLayout layout, @NonNull CharSequence text) {
  layout.addTab(layout.newTab().setText(text)); // same layout creates AND adds
}

Prevention

When it happens

Trigger: Creating a tab with tabLayout1.newTab() and adding it via tabLayout2.addTab(tab) or tabLayout2.addTab(tab, position, true).

Common situations: Two TabLayouts in one screen (top + bottom, or tabs + navigation) and copy-pasted setup code; recreating tabs after a configuration change using the wrong saved TabLayout reference; helper methods that take the wrong TabLayout parameter.

Related errors


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