Description
Some signInWithWebUI calls on Android fail with UserCancelledException well under 2 seconds after launch — before the Hosted UI page can render, so no user action is possible. Lifecycle telemetry (Sentry breadcrumbs) shows the app backgrounded for as little as 420–480ms before the cancel trampoline (AmplifyAuthCognitoPlugin.onActivityResult → CUSTOM_TAB_CANCEL_EXTRA intent → cancelCurrentOperation) brings the activity back to the foreground and the call fails with HostedUiException.CANCELLED.
Why we believe this is a race in the cancel detection rather than a configuration issue:
Categories
Steps to Reproduce
Not deterministically reproducible (timing race). Observed in production on Samsung, Pixel, and Motorola devices, Android 10–16, always with the same signature: app backgrounds for <1.5s, returns without user interaction, signInWithWebUI throws UserCancelledException. One suggestive variant: call signOut() (which opens the /logout Custom Tab), then promptly signInWithWebUI(provider: AuthProvider.google).
Screenshots
No response
Platforms
Flutter Version
3.41.5,
Amplify Flutter Version
2.6.5
Deployment Method
Custom Pipeline
Schema
Description
Some signInWithWebUI calls on Android fail with UserCancelledException well under 2 seconds after launch — before the Hosted UI page can render, so no user action is possible. Lifecycle telemetry (Sentry breadcrumbs) shows the app backgrounded for as little as 420–480ms before the cancel trampoline (AmplifyAuthCognitoPlugin.onActivityResult → CUSTOM_TAB_CANCEL_EXTRA intent → cancelCurrentOperation) brings the activity back to the foreground and the call fails with HostedUiException.CANCELLED.
Why we believe this is a race in the cancel detection rather than a configuration issue:
The timing is bimodal: genuine user cancellations in our telemetry show 9–73 seconds of browser time before returning; a distinct second mode sits at 0.42s / 0.48s / 1.3s.
The same configuration succeeds normally otherwise, and retrying immediately
typically succeeds — a redirect/config error would fail deterministically. Current Flutter templates ship launchMode="singleTop" (our manifest as well). The trampoline's ordering argument ("our intent is guaranteed to be handled after the success intent") may not hold in that task topology when onActivityResult is delivered early (e.g. activity recreation under the tab, or the browser opening in a separate task).
Similar symptom family: Calling activity is getting destroyed, when opening custom tab browser for signInWithWebUI and showing user cancelled authorization flow; but selecting account signs in successfully. amplify-android#2475 (activity destroyed during the tab hand-off → spurious cancel) and Exception not thrown when user cancel the auth flow in android #819 (inverse race: cancel not delivered).
Ask:
launchMode="singleTop", and consider guarding against results that arrive within a
minimal window after launch / while the Custom Tab task is still alive — this
matches our observed sub-500ms cancellations.
few seconds after signOut()'s /logout Custom Tab round-trip (cf. Unexpected behaviour during Amplify.Auth.signOut() after Amplify.Auth.signInWithWebUI() #1452). We cannot
confirm from app-side telemetry whether that is a stale trampoline from the prior
tab or the same race as (1) — flagging it in case it helps narrow the mechanism.
Categories
Steps to Reproduce
Not deterministically reproducible (timing race). Observed in production on Samsung, Pixel, and Motorola devices, Android 10–16, always with the same signature: app backgrounds for <1.5s, returns without user interaction, signInWithWebUI throws UserCancelledException. One suggestive variant: call signOut() (which opens the /logout Custom Tab), then promptly signInWithWebUI(provider: AuthProvider.google).
Screenshots
No response
Platforms
Flutter Version
3.41.5,
Amplify Flutter Version
2.6.5
Deployment Method
Custom Pipeline
Schema