material-components/material-components-android · error · IllegalArgumentException
Tab does not belong to this TabLayout.
Error message
Tab does not belong to this TabLayout.
What it means
removeTab(tab) verifies tab.parent == this; Tab objects carry an internal owner reference set when created via newTab(). Removing a tab owned by another TabLayout (or one never added) throws IllegalArgumentException, since the owning layout's tab list is the only valid source of positions.
Source
Thrown at lib/java/com/google/android/material/tabs/TabLayout.java:1063
/**
* Returns the position of the current selected tab.
*
* @return selected tab position, or {@code -1} if there isn't a selected tab.
*/
public int getSelectedTabPosition() {
return selectedTab != null ? selectedTab.getPosition() : -1;
}
/**
* Remove a tab from the layout. If the removed tab was selected it will be deselected and another
* tab will be selected if present.
*
* @param tab The tab to remove
*/
public void removeTab(@NonNull Tab tab) {
if (tab.parent != this) {
throw new IllegalArgumentException("Tab does not belong to this TabLayout.");
}
removeTabAt(tab.getPosition());
}
/**
* Remove a tab from the layout. If the removed tab was selected it will be deselected and another
* tab will be selected if present.
*
* @param position Position of the tab to remove
*/
public void removeTabAt(int position) {
final int selectedTabPosition = selectedTab != null ? selectedTab.getPosition() : 0;
removeTabViewAt(position);
final Tab removedTab = tabs.remove(position);
if (removedTab != null) {
removedTab.reset();View on GitHub (pinned to ac7e18efee)
Solutions
- Remove by position instead: tabLayout.removeTabAt(position) using a position you track.
- Prefer getTabAt(position) to fetch the tab right before removal so it is guaranteed to belong to this layout.
- To clear all tabs, call tabLayout.removeAllTabs() rather than iterating cached Tab objects.
Example fix
// before tabLayout.removeTab(cachedTab); // cachedTab from another/stale TabLayout // after Tab current = tabLayout.getTabAt(position); if (current != null) tabLayout.removeTab(current);
Defensive patterns
Strategy: validation
Validate before calling
// Prefer positional removal, which cannot cross-own:
public static void removeTabAtSafe(@NonNull TabLayout layout, int position) {
if (position >= 0 && position < layout.getTabCount()) layout.removeTabAt(position);
} Prevention
- Remove by position or via getTabAt(position), never via cached Tab references.
- Use removeAllTabs() when clearing.
- Drop cached Tab objects whenever the tab list is rebuilt.
When it happens
Trigger: Calling tabLayout.removeTab(tab) where tab came from a different TabLayout's newTab(), or removing the same tab twice after it was already removed and its parent reference cleared.
Common situations: Multiple TabLayouts sharing tab-building code; caching Tab references across adapter refreshes and removing stale tabs; races between tab removal and UI recreation.
Related errors
- Tab belongs to a different TabLayout.
- is not a valid TabIndicatorAnimationMode
- Only TabItem instances can be added to TabLayout
- Tab not attached to a TabLayout
- No suitable parent found from the given view. Please provide
AI-assisted analysis of material-components/material-components-android@ac7e18efee (2026-08-14).
Data as JSON: /api/errors/4c9227b5ede3e3b0.
Report an issue: GitHub.