Repository navigation
[Bug]: Android app doesn't handle network changes gracefully, particularly bad network connectivity #12573
Description
Activity
- addedbugSomething is broken or behaving incorrectly.Something is broken or behaving incorrectly.needs-triageIssue needs maintainer review and initial categorization.Issue needs maintainer review and initial categorization.
on Sep 19, 2026 Triage
This is a real mobile reconnect gap on current
main. The form listed apps/web, but the title and repro are the Android app. No existing issue looks like a duplicate.What happens
The connection stack treats the network as a boolean:
unknown/offline/online. Mobile mapsexpo-networkdown to that using onlyisConnected, and ignores interface type (wifivscellular):t3code/apps/mobile/src/connection/platform.ts
Lines 37 to 45 in dfbb11b
function networkStatus(state: Network.NetworkState): "unknown" | "offline" | "online" { if (state.isConnected === false) { return "offline"; } if (state.isConnected === true) { return "online"; } return "unknown"; } A connected session is only torn down on a network event when the status becomes offline:
t3code/packages/client-runtime/src/connection/supervisor.ts
Lines 404 to 408 in dfbb11b
case "NetworkChanged": if (next.network === "offline") { return false; } break; Same-status updates are dropped, so
CELLULAR → WIFI(or “Wi‑Fi up, then cell drops”) never becomes a reconnect signal ifisConnectedstaystrue:t3code/packages/client-runtime/src/connection/supervisor.ts
Lines 749 to 759 in dfbb11b
yield* connectivity.changes.pipe( Stream.runForEach((network) => Ref.modify(intent, (current) => current.network === network ? [false, current] : ([true, { ...current, network }] as const), ).pipe( Effect.flatMap((changed) => changed ? signal({ _tag: "NetworkChanged", network }) : Effect.void, ), ), ), Effect.forkScoped, The live WebSocket is not probed on a path change. A liveness probe / forced replace happens on app resume, not while the app stays in the foreground:
t3code/apps/mobile/src/connection/app-state-wakeups.ts
Lines 10 to 18 in dfbb11b
export function mobileApplicationActiveWakeup( backgroundedAtMs: number | null, activeAtMs: number, ): MobileApplicationActiveWakeup { return backgroundedAtMs !== null && activeAtMs - backgroundedAtMs >= MOBILE_BACKGROUND_RECONNECT_AFTER_MS ? "application-active-reconnect" : "application-active-probe"; } Session death is only observed from socket/subscription close. There is no client ping timeout that would notice a half-open socket still bound to the old interface:
t3code/packages/client-runtime/src/rpc/session.ts
Lines 388 to 391 in dfbb11b
closed: Effect.raceFirst( Deferred.await(disconnected), Deferred.await(configSubscriptionClosed), ), That matches the report: start on cell, join Wi‑Fi, lose cell, stay “online,” and the environment has to be reconnected by hand. Android dual-stack / default-route handoff is the usual trigger; iOS can hit the same shared path.
Related work
- fix(mobile): probe network changes and refresh activity leases #5154 (
fix(mobile): probe network changes and refresh activity leases) targeted this exact miss — emitnetwork-path-changedwhen the interface changes while still online, then probe. Closed unmerged; that wakeup does not exist onmain. - feat(mobile): keep Android connections alive in the background #5179 is adjacent (keep Android connections alive in the background), not a substitute for foreground interface handoff.
Workaround
Background the app and come back (a resume of 10s+ forces
application-active-reconnect), or reconnect the environment from the UI.Helpful extras (not blocking)
App version, Android version, and whether this is LAN / Tailscale / T3 Connect. Also whether the app stayed in the foreground the whole time.
- fix(mobile): probe network changes and refresh activity leases #5154 (
- addedacceptedfeature request acceptedfeature request acceptedvia-triageFiled through npx t3 triageFiled through npx t3 triageand removedneeds-triageIssue needs maintainer review and initial categorization.Issue needs maintainer review and initial categorization.
on Sep 19, 2026
Before submitting
Area
apps/web
Steps to reproduce
Start the app on cellular, move into an area and connect to WiFi, and move to a place where the cellular signal is lost. Connections need to be manually reconnected
Expected behavior
App should detect network change and re establish web sockets
Actual behavior
Phone doesn't detect network change
Impact
Major degradation or frequent failure
Version or commit
No response
Environment
No response
Logs or stack traces
Screenshots, recordings, or supporting files
No response
Workaround
No response