{"record":{"id":"4c9227b5ede3e3b0","repo":"material-components/material-components-android","slug":"tab-does-not-belong-to-this-tablayout","errorCode":null,"errorMessage":"Tab does not belong to this TabLayout.","messagePattern":"Tab does not belong to this TabLayout\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"lib/java/com/google/android/material/tabs/TabLayout.java","lineNumber":1063,"sourceCode":"\n  /**\n   * Returns the position of the current selected tab.\n   *\n   * @return selected tab position, or {@code -1} if there isn't a selected tab.\n   */\n  public int getSelectedTabPosition() {\n    return selectedTab != null ? selectedTab.getPosition() : -1;\n  }\n\n  /**\n   * Remove a tab from the layout. If the removed tab was selected it will be deselected and another\n   * tab will be selected if present.\n   *\n   * @param tab The tab to remove\n   */\n  public void removeTab(@NonNull Tab tab) {\n    if (tab.parent != this) {\n      throw new IllegalArgumentException(\"Tab does not belong to this TabLayout.\");\n    }\n\n    removeTabAt(tab.getPosition());\n  }\n\n  /**\n   * Remove a tab from the layout. If the removed tab was selected it will be deselected and another\n   * tab will be selected if present.\n   *\n   * @param position Position of the tab to remove\n   */\n  public void removeTabAt(int position) {\n    final int selectedTabPosition = selectedTab != null ? selectedTab.getPosition() : 0;\n    removeTabViewAt(position);\n\n    final Tab removedTab = tabs.remove(position);\n    if (removedTab != null) {\n      removedTab.reset();","sourceCodeStart":1045,"sourceCodeEnd":1081,"githubUrl":"https://github.com/material-components/material-components-android/blob/ac7e18efeefb331850c561faf9ab8bf81d27ba68/lib/java/com/google/android/material/tabs/TabLayout.java#L1045-L1081","documentation":"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.","triggerScenarios":"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.","commonSituations":"Multiple TabLayouts sharing tab-building code; caching Tab references across adapter refreshes and removing stale tabs; races between tab removal and UI recreation.","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."],"exampleFix":"// before\ntabLayout.removeTab(cachedTab); // cachedTab from another/stale TabLayout\n\n// after\nTab current = tabLayout.getTabAt(position);\nif (current != null) tabLayout.removeTab(current);","handlingStrategy":"validation","validationCode":"// Prefer positional removal, which cannot cross-own:\npublic static void removeTabAtSafe(@NonNull TabLayout layout, int position) {\n  if (position >= 0 && position < layout.getTabCount()) layout.removeTabAt(position);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["tablayout","tabs","android","ui"],"backgroundTag":null,"analyzedSha":"ac7e18efeefb331850c561faf9ab8bf81d27ba68","analyzedAt":"2026-08-14T15:35:35.735Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}