Skip to content

fix(tab): avoid TabController crash when all conditional tabs are hidden#2255

Closed
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-remediation-0747
Closed

fix(tab): avoid TabController crash when all conditional tabs are hidden#2255
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-remediation-0747

Conversation

@cursor
Copy link
Copy Markdown

@cursor cursor Bot commented Jun 3, 2026

Description

Resubmits the fix from #2241 (closed without merge on 2026-06-01). When every tab in a TabBar or ScrollableTabBar uses a conditional visible binding and all bindings evaluate to false at runtime, handleConditionalTabs() leaves zero visible items and _reinitializeTabController() created TabController(length: 0), which violates Flutter’s length >= 1 assertion and crashes the app.

Bug and impact

Trigger: A screen with tabs where each item has visible: ${someCondition}, and runtime evaluation sets every condition to false (e.g. filter state hides all tabs).

Impact: Framework assertion failure / app crash during tab controller reinitialization.

Root cause

updateVisibleItems() can produce an empty visible tab list, but _initializeTabController() passed items.length directly to TabController without guarding zero.

Fix

  • Add effectiveTabControllerLength() so controller length is never below 1 when no tabs are visible (UI already returns SizedBox.shrink() when items.isEmpty).
  • Skip notifyListener on the placeholder controller when there are no visible tabs.
  • Apply the same length guard to ScrollableTabBar and clamp selectedIndex when reinitializing.

Validation

  • Added modules/ensemble/test/effective_tab_controller_length_test.dart.
  • Flutter SDK was not available on the automation runner PATH; please run flutter test test/effective_tab_controller_length_test.dart from modules/ensemble.

Duplicate check

Open in Web View Automation 

When every tab has a conditional visible binding that evaluates to false,
handleConditionalTabs() can leave zero visible items. TabController
asserts length >= 1, which crashed the app during _reinitializeTabController.

Use a placeholder length of 1 when no tabs are visible (build already
returns shrink) and skip tab selection listeners until tabs return.
Align ScrollableTabBar with the same guard and selectedIndex clamp.

Co-authored-by: Sharjeel Yunus <sharjeelyunus@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants