Skip to content

fix(mobile): avoid stuck WebBrowser auth session on Android - #4376

Merged
iscekic merged 1 commit into
mainfrom
fix/mobile-auth-session-stuck
Jul 3, 2026
Merged

fix(mobile): avoid stuck WebBrowser auth session on Android#4376
iscekic merged 1 commit into
mainfrom
fix/mobile-auth-session-stuck

Conversation

@iscekic

@iscekic iscekic commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes Sentry issue KILO-APP-22: on Android, sign-in could permanently fail with The WebBrowser's auth session is in an invalid state with a redirect handler set when it should not be until the app was restarted.

Fixes KILO-APP-22

Mechanism

Android has no native auth session, so expo-web-browser's openAuthSessionAsync falls back to a JS polyfill that keeps module-level state (_redirectSubscription, _onWebBrowserCloseAndroid). The polyfill only resolves on an AppState active transition and swallows the first AppState event after module load, so a session can get stuck unresolved — after which every subsequent openAuthSessionAsync call throws, making sign-in impossible.

Fix

We never rely on the redirect deep-link on Android — the app polls the server for device-auth approval. So on Android we bypass the broken polyfill entirely and use WebBrowser.openBrowserAsync instead (new openAuthBrowser helper used by both start() and openBrowser()). Also added error handling to openBrowser(), which previously surfaced throws as unhandled rejections; it now sets an error state with a user-visible message.

@iscekic iscekic self-assigned this Jul 3, 2026
@iscekic
iscekic enabled auto-merge (squash) July 3, 2026 11:05
// module-level state that can get stuck and reject every future call
// (KILO-APP-22). We poll the server for approval instead of relying on a
// redirect, so a plain browser open is all Android needs.
async function openAuthBrowser(url: string) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Android now opens the browser with openBrowserAsync, but approval still dismisses via dismissAuthSession()

WebBrowser.dismissAuthSession() only affects sessions started with openAuthSessionAsync; it has no effect on a browser opened with openBrowserAsync. Since Android now goes through openBrowserAsync in both start() and openBrowser(), the tab opened on Android will no longer auto-close when polling detects approval (the case 200: branch in poll() still calls WebBrowser.dismissAuthSession()). The user will have to manually switch back to the app after approving sign-in on Android. Consider calling WebBrowser.dismissBrowser() on Android in that success path as well.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked against expo-web-browser 55.0.16 source: the Android native module (WebBrowserModule.kt) implements no dismissal at all — no dismissBrowser, no dismissAuthSession. Custom tabs can't be closed programmatically; return-to-app is handled by BrowserProxyActivity when the user closes the tab. dismissAuthSession() on Android has always taken the JS fallback branch targeting ExponentWebBrowser.dismissBrowser, which doesn't exist there — so the tab never auto-closed on Android before this PR either, and dismissBrowser() (ExponentWebBrowser.dismissBrowser?.()) would be a no-op. No regression.

The valid part: with Android no longer opening an auth session, the unconditional dismissAuthSession() in poll() is pointless there and a latent UnavailabilityError throw site inside the poll's try block. Follow-up guards it to iOS: #4377

@kilo-code-bot

kilo-code-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

On Android, the new openAuthBrowser helper switches to WebBrowser.openBrowserAsync, but the approval path still calls WebBrowser.dismissAuthSession(), which won't close a browser opened that way.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
apps/mobile/src/lib/auth/use-device-auth.ts 29 dismissAuthSession() doesn't dismiss a browser opened via openBrowserAsync on Android, so the tab won't auto-close on approval
Files Reviewed (1 file)
  • apps/mobile/src/lib/auth/use-device-auth.ts - 1 issue

Fix these issues in Kilo Cloud


Reviewed by claude-sonnet-5-20260630 · Input: 24 · Output: 12.1K · Cached: 576.2K

Review guidance: REVIEW.md from base branch main

@iscekic
iscekic merged commit 2539134 into main Jul 3, 2026
19 checks passed
@iscekic
iscekic deleted the fix/mobile-auth-session-stuck branch July 3, 2026 11:07
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