Repository navigation
[Bug]: Duplicate top header rendered in Android split-screen view #13498
Description
Activity
Triage: #13498 Duplicate top header in Android split-screen
Verdict: Valid. Still present on
main(f3cb2a1fee). Not a duplicate. No fix in a newer release.Severity: Low. The Threads screen stays usable, but split-screen (and any later resize) stacks two brand bars and burns vertical space.
What happened
On Android Alpha, entering split-screen shows two stacked
T3 Code ALPHAbars on the Threads screen. The upper bar is only the brand, padded for the status bar. The lower bar repeats the brand and adds Search and Settings. The screenshot is a vivo PD2193F (Android 14,PD2193F_EX_A_14.2.12.0.W30.V000L1), landscape, T3 Code in the left pane, 2404×1080, taken 2026-09-25 02:51 +05:30. The Alpha badge matches the production stage label.Diagnosis
Android compact Home already draws its own header. The native stack header is supposed to stay hidden, and a width change turns it back on.
On the compact path,
HomeRouteScreenre-applies the iOS brand header withheaderShown: truewheneverwindowWidthchanges. That exists so the native title can be restored after leaving the in-app split layout, and so the connection-status title gets a new max width.optionsVersion={windowWidth}was added in#8624(053affbed26).{/* Restore the header after leaving split view; screen options are shallow-merged. The brand slot also doubles as the connection status surface while an environment reconnects. */} <NativeStackScreenOptions optionsVersion={windowWidth} options={{ ...getConnectionAwareBrandHeaderOptions({ headerWidth: windowWidth, onOpenEnvironments: () => navigation.navigate("SettingsSheet", { screen: "SettingsContent", params: { screen: "SettingsEnvironments" }, }), }), headerShown: true, }} />
Android does not use that native bar.
HomeHeader.android.tsxhides it and rendersMaterialThreadListToolbar, which is the bar with the brand plus Search and Settings.return ( <> <NativeStackScreenOptions options={{ headerShown: false }} /> <MaterialThreadListToolbar searchQuery={props.searchQuery} onSearchQueryChange={props.onSearchQueryChange} filterActions={menuActions} filterCustomized={hasCustomListOptions} onFilterAction={handleMenuAction} onOpenSettings={props.onOpenSettings} onOpenEnvironments={props.onOpenEnvironments} />
NativeStackScreenOptionsskipssetOptionswhen the options signature is unchanged.{ headerShown: false }never changes, so that hide runs once at mount and then stops. The sibling that setsheaderShown: trueruns again on every width change and wins, becausesetOptionsshallow-merges. The native header comes back above the Material toolbar.That matches the screenshot. The native title is
CompactBrandTitle(wordmark, "Code", and the Alpha badge) with no trailing actions. Search and Settings exist only on the in-flow toolbar. The native bar also carries the status-bar inset. The Home screen's static options inStack.tsxalready start fromheaderShown: trueplus the same brand title, so the first paint is only correct because the Android hide lands after it.A phone stays on this compact path in split-screen. Split layout needs width ≥ 720 and height ≥ 600. The screenshot is landscape (device height 1080 px), so the pane stays under the height floor. The in-app split branch is not what the user hit. That branch hides the native header and titles the detail pane "Threads".
Leaving split-screen does not clear it. Any later width change, including returning to portrait, re-applies
headerShown: true. The bad header sticks until Home remounts. A cold start in the final window size hides the native bar again, until the next resize. Rotation and freeform resize on a phone should hit the same path.Steps to reproduce
- Cold-start the Android app and open Threads. One brand bar, with Search and Settings.
- Enter split-screen so the window width changes while the pane stays compact (landscape side-by-side, as in the screenshot).
- Two
T3 Code ALPHAbars are stacked. Only the lower one has Search and Settings. - Exit split-screen. The duplicate remains until the app is restarted without a further resize.
Environment
Android Alpha (production stage label). Reporter did not pin a build number. Inspected tree is
mainatf3cb2a1fee, app version1.3.1inapps/mobile/app.config.ts. Device from the screenshot: vivo PD2193F, Android 14. This VM has no Android emulator, so this is source plus the screenshot, not a live run.Related issues
No matching issue besides #13498. #10629 is the iPad Threads toolbar disappearing after resize, a different platform and failure.
Fix
On Android, the compact
HomeRouteScreenoptions should keepheaderShown: falseacross width changes. iOS should still passheaderShown: trueso the native bar returns after the in-app split layout. Re-applying the hide by bumping the Android options version is weaker, because it depends on effect order.Workaround
Force-quit and reopen after the window is already the size you want. Resizing again brings the second bar back.
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.acceptedfeature request acceptedfeature request acceptedvia-triageFiled through npx t3 triageFiled through npx t3 triage
on Sep 24, 2026 Also reproducing on a Samsung Galaxy S25 Ultra (latest Android/One UI, latest T3 Code Android Alpha from the store), in portrait, full-screen.
As far as I can tell I did not use split-screen or rotate the phone before it appeared. I saw the same thing as the original report on the Threads screen: two stacked
T3 Code ALPHAbars. The upper one is only the brand under the status bar, and the lower one has the brand plus Search and Settings.So the trigger may be wider than split-screen or rotation. Something else that changes the window width, or the
headerShown: truere-apply at mount, might be enough. The fix proposed in the triage (keepheaderShown: falseon Android compact Home across width changes) should cover this case too.I have a screenshot. I've left it out because it shows private thread titles.
Before submitting
Area
apps/mobile
Steps to reproduce
Expected behavior
A single top header bar is displayed containing the branding, search, and settings icons, maximizing usable screen real estate.
Actual behavior
The T3 Code top header appears twice stacked vertically:
T3 Code ALPHAalong with system status bar inset padding.T3 Code ALPHAalongside the search and settings action buttons.In split-screen view where vertical space is already constrained, this duplicate top bar wastes significant screen area.
Impact
Minor bug or occasional failure
Version or commit
Android app (Alpha release)
Environment
Android
Logs or stack traces
No response
Screenshots or supporting files
Workaround
No response